大数据集的参数扩展速度慢

时间:2013-02-19 20:59:28

标签: bash

如果我从文件中取出前1,000个字节,Bash可以很快地替换一些字符

$ cut -b-1000 get_video_info
muted=0&status=ok&length_seconds=24&endscreen_module=http%3A%2F%2Fs.ytimg.com%2F
yts%2Fswfbin%2Fendscreen-vfl4_CAIR.swf&plid=AATWGZfL-Ysy64Mp&sendtmp=1&view_coun
t=3587&author=hye+jeong+Jeong&pltype=contentugc&threed_layout=1&storyboard_spec=
http%3A%2F%2Fi1.ytimg.com%2Fsb%2FLHelEIJVxiE%2Fstoryboard3_L%24L%2F%24N.jpg%7C48
%2327%23100%2310%2310%230%23default%23cTWfBXjxZMDvzL5cyCgHdDJ3s_A%7C80%2345%2324
%2310%2310%231000%23M%24M%23m1lhUvkKk6sTnuyKXnPBojTIqeM%7C160%2390%2324%235%235%
231000%23M%24M%23r-fWFZpjrP1oq2uq_Y_1im4iu2I%7C320%23180%2324%233%233%231000%23M
%24M%23uGg7bth0q6XSYb8odKLRqkNe7ao&approx_threed_layout=1&allow_embed=1&allow_ra
tings=1&url_encoded_fmt_stream_map=fallback_host%3Dtc.v11.cache2.c.youtube.com%2
6quality%3Dhd1080%26sig%3D610EACBDE06623717B1DC2265696B473C47BD28F.98097DEC78411
95A074D6D6EBFF8B277F9C071AE%26url%3Dhttp%253A%252F%252Fr9---sn-q4f7dney.c.youtub
e.com%252Fvideoplayback%253Fms%253Dau%2526ratebypass%253Dyes%2526ipbits%253D8%25
26key%253Dyt1%2526ip%253D99.109.97.214%2

$ read aa < <(cut -b-1000 get_video_info)

$ time set "${aa//%/\x}"

real    0m0.025s
user    0m0.031s
sys     0m0.000s

但是,如果我占用10,000个字节,它会显着减慢

$ read aa < <(cut -b-10000 get_video_info)

$ time set "${aa//%/\x}"

real    0m8.125s
user    0m8.127s
sys     0m0.000s

我读过Greg Wooledge’s post但是它没有解释为什么Bash参数扩展很慢。

2 个答案:

答案 0 :(得分:8)

对于 why ,您可以在bash源代码的pat_subst subst.c中看到此代码的实现。

对于字符串中的每个匹配项,字符串的长度计数多次(pat_substmatch_patternmatch_upattern),两者都作为C字符串计算,并且作为多字节字符串。这使得函数既不必要慢,更重要的是,复杂性是二次的。

这就是为什么它对于较大的输入来说很慢,这是一个漂亮的图表:

Quadratic runtime in shell replacements

至于解决方法,只需使用sed即可。它更有可能针对字符串替换操作进行优化(尽管你应该知道POSIX每行仅保证8192个字节,即使GNU sed处理任意大的)。

答案 1 :(得分:1)

最初,较旧的shell和其他实用程序强加了LINE_MAX = 2048 因为这种原因在文件输入上。对于巨大的变量,bash没有 把它们停在记忆中的问题。但替代需要至少两个 并发副本。还有很多颠簸:作为一群人物 删除整个字符串得到重写。一遍又一遍。

有这样的工具 - sed是首选。 bash是一个 遥远的第二选择。 sed适用于流,bash适用于内存块。

另一种选择: bash是可扩展的 - 你可以编写自定义的C代码来填充东西 当bash不打算这样做的时候。

CFA Johnson有关于如何做到这一点的好文章:

有些人准备加载内置版:

http://cfajohnson.com/shell/bash/loadables/

DIY内置者解释说:

http://cfajohnson.com/shell/articles/dynamically-loadable/