加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

unix打印 讲个小故事:Unix的yes命令

发布时间:2022-11-04 14:02:02 所属栏目:Unix 来源:未知
导读:
你知道的最简单的Unix命令是什么?
是echo,它把字符串打印到终端,然后返回true,它的返回值总是0.
除了echo,还有一个命令也很简单,它是yes。如果你运行它,不带任何参数,它会无限输出

unix文件系统_unix入门经典_unix打印

你知道的最简单的Unix命令是什么?

是echo,它把字符串打印到终端,然后返回true,它的返回值总是0.

除了echo,还有一个命令也很简单,它是yes。如果你运行它,不带任何参数,它会无限输出字母y到屏幕上,其中每一个y都独占一行。

unix文件系统_unix打印_unix入门经典

感觉很没用?其实它是很有用的

安装程序的时候,有的程序需要你不断地按y和回车,安装进程才能继续工作。yes命令可以解救你!它帮你输入y和回车,这样你就可以安心去看唐老鸭动画片了。

让我们自己编写一个yes命令

这是一个基本的版本,嗯,用BASIC写的

然后我们再写一个Python版本的:

感觉很简单?等等unix打印,先别急。事实上上面两个程序都很慢。

让我们对比一下系统内置的版本:

我要自己写一个快一点的版本,我尝试用Rust去写:

unix打印_unix文件系统_unix入门经典

稍微解释一下这段程序:

让我们测试一下

unix入门经典_unix文件系统_unix打印

额,这就尴尬了,比Python的版本还慢。这让我很惊讶,于是我到处寻找该命令的C源码。

下面这段代码是yes命令作为系统命令发布的第一个版本,它发布在Unix 7上,由Ken Thompson于1979年1月10日编写。

unix打印_unix入门经典_unix文件系统

好像没什么特殊的地方。

如今,这个命令被放在GNU coreutils中,当前这个版本用了整整128行代码来完成这个功能,你可以在github上找到它的源码:。已经过了25年,这个命令居然仍然在更新中!最近一次更新大概在一年前。它的效率非常高

unix文件系统_unix入门经典_unix打印

最关键的是最后这部分

unix文件系统_unix入门经典_unix打印

哇哦!他们就是用了一个缓冲区来让写入操作变得更快。

缓冲区大小由常量BUFSIZ控制,这个变量在各个系统中不同,以便能最优化写入效率。在我的系统中,它被定义为1024bytes,我把它改为8192bytes,发现程序更快了。

所以,参考这个思路我更新了我的Rust程序。

unix入门经典_unix打印_unix文件系统

一个重要的细节是,缓冲区大小必须是4的倍数,这样来保证内存数据的对齐。

我这个程序可以达到51.3MiB/s,这个速度已经快于我的系统自带版本了,但是仍然比Reddit论坛上网友晒出的程序慢很多,网友的程序可以达到10.2GiB/s。

再更新

我再次求助于社区,有人给我指出了之前网上对这个问题的一些讨论。下面是他们优化的代码,在我的机器上运行效果达到了3GB/s。

unix文件系统_unix入门经典_unix打印

unix打印_unix入门经典_unix文件系统

unix文件系统_unix打印_unix入门经典

现在这个程序的思路已经完全不同了!

我们准备了一个字符串缓冲区,这个缓冲区在循环中被不断复用。

标准输出用锁保护起来。所以,相比于不断地请求锁、释放锁,我们把标准输出一直占用着。

我们使用平台原生的 std::ffi::OsString 和 std::borrow::Cow 来避免不必要的分配。

这里面唯一我能做出的改进贡献就是移除一个没用的小变量。

学到了什么?

很小的一个命令yes里面居然如此复杂。它使用了输出缓冲区和内存对齐来提高性能。重新实现这些小程序很有趣,同时我对它们所使用的提高性能的技巧也感到惊叹不已!

英文原文:

译者:诗书塞外

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章