ksh93这么快吗?


9

因此,总的来说,我倾向于寻找sed文本处理工具,尤其是大文件,并且通常避免在shell本身中做这些事情。

我认为,这可能会改变。我在四处闲逛,man ksh我注意到了这一点:

<#pattern     Seeks forward to the beginning of the
              next line containing pattern.

<##pattern    The same as <# except that  the  por
              tion  of  the file that is skipped is
              copied to standard output.

对现实世界的有用性表示怀疑,我决定尝试一下。我做了:

seq -s'foo bar
' 1000000 >file

...对于一百万行数据如下所示:

1foo bar
...
999999foo bar
1000000

...并反对sed

p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"    
do </tmp/file eval "time ( $c )"
done | wc -l

因此,这两个命令都应达到999999foo bar,并且它们的模式匹配实现必须至少评估每行的开头和结尾才能这样做。他们还必须对照否定模式来验证第一个字符。这很简单,但是...结果不是我期望的:

( sed '/^[^0-8]99999.*bar/q' ) \
    0.40s user 0.01s system 99% cpu 0.419 total
( ksh -c ':<##@(~(E)^[^0-8]99999.*bar)' ) \
    0.02s user 0.01s system 91% cpu 0.033 total
1999997

ksh在这里使用ERE和sedBRE。我ksh之前使用shell模式做过同样的事情,但是结果没有不同。

无论如何,这是一个相当大的差异- ksh胜过sed10倍。我之前读过David Korn编写了自己的io lib并将其实现ksh-可能与此有关吗?-但我对此一无所知。外壳怎么这么好?

更令我惊讶的是,ksh确实确实将偏移量留在了您要问的地方。要(几乎)(GNU)中 获得相同的结果,sed您必须使用-u- 非常慢

这是一个grepv。ksh测试:

1000000         #grep + head
( grep -qm1 '^[^0-8]99999.*bar'; head -n1; ) \
    0.02s user 0.00s system 90% cpu 0.026 total
999999foo bar   #ksh + head
( ksh -c ':<#@(~(E)^[^0-8]99999.*bar)'; head -n1; )  \
    0.02s user 0.00s system 73% cpu 0.023 total

kshgrep在这里跳动-但并非总是如此-它们几乎是并列的。尽管如此,这还是非常出色的,并且 ksh提供了先行功能- head的输入匹配之前开始。

我想这似乎太不可思议了。这些命令在后台有何不同之处?

哦,显然这里没有子shell:

ksh -c 'printf %.5s "${<file;}"'

pattern正则表达式还是更简单的shell模式?
muru

@muru-也可以,但是我不太擅长更改周围环境。在示例中,它是一个外壳模式-默认。
mikeserv 2014年

@muru-我添加了一个w /正则表达式。
mikeserv

Answers:


8

ksh不仅使用sfio,而且使用其自己的自定义内存分配器。

尽管如此,我的猜测是在这种情况下sfio有所作为。我只是尝试在strace下运行您的示例,可以看到ksh调用读/写〜200次(65 KB块),而sed进行了大约3400次(4 KB块)。使用sed -u,我的笔记本电脑几乎融化了,每个字节读取一次,每行写入一次。Ksh简单地使用lseek。Grep使用约400次读取(32 KB块)。


是的-没有缓冲不是为了胆小的人。我想知道kshregex引擎是否像io一样高效?无论如何,非常感谢您的回答。对您的笔记本电脑致歉。但是自定义内存分配器呢?你还有其他吗?
mikeserv 2014年

1
可悲的是没有。您当然可以从at&t网站下载源代码,仅此而已。该库称为AST,包含分配器,正则表达式引擎和许多其他内容。因此,将所有这些东西组合在一起使ksh更快是完全有可能的。
米罗斯拉夫·法郎2014年


谢谢-这看起来也很有希望:AST软件集合中可用的某些组件包括:POSIX命令AST集合中提供了大多数标准POSIX命令。许多代码被编码为库函数,可以作为内置命令添加到ksh中,从而显着提高性能。-现在我要弄清楚如何建造它,
mikeserv 2014年

1
可以构建@mikeserv ksh以使用Phong Vo的vmalloc分配器。该链接上提供期刊文章。
Mark Plotnick 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.