当前位置: 首页 > 面试题库 >

与cat相比,bash同时读取循环极慢,为什么呢?

欧阳成弘
2023-03-14
问题内容

一个简单的测试脚本在这里:

while read LINE; do
        LINECOUNT=$(($LINECOUNT+1))
        if [[ $(($LINECOUNT % 1000)) -eq 0 ]]; then echo $LINECOUNT; fi
done

当我这样做时cat my450klinefile.txt | myscript,CPU锁定为100%,它每秒可以处理大约1000行。大约需要5分钟来处理`cat my450klinefile.txt

/dev/null`半秒钟内的操作。

有没有一种 更有效的方法
来执行此操作。我只需要从stdin中读取一行,计算字节数,然后将其写到命名管道中即可。但是,即使这个例子的速度也不可能太慢。

每输入1 Gb输入行,我需要执行一些更复杂的脚本操作(关闭并打开一些将数据馈入的管道)。


问题答案:

原因while read很慢,因为需要外壳程序对每个字节进行系统调用。它不能从管道读取较大的缓冲区,因为外壳程序不得从输入流读取多行内容,因此必须将每个字符与换行符进行比较。如果您stracewhile read循环上运行,您可以看到此行为。此行为是可取的,因为它可以可靠地执行以下操作:

while read size; do dd bs=$size count=1 of=file$(( i++ )); done

其中循环内的命令从外壳程序读取的同一流中读取。如果外壳程序通过读取大缓冲区消耗了大量数据,则内部命令将无法访问该数据。不幸的副作用是,read它的运行速度太慢了。



 类似资料:
  • 问题内容: 从2010年的计算机语言基准游戏中可以看出: Go平均比C慢10倍 Go比Java慢3倍! 考虑到Go编译器会生成要执行的本机代码,这怎么可能? Go的编译器不成熟?还是Go语言存在一些内在问题? 编辑: 大多数答案否认Go语言的内在缓慢,声称问题出在不成熟的编译器中。 因此,我进行了一些自己的测试来计算斐波那契数:迭代算法在Go(freebsd,6g)中以与C(带有O3选项)一样的速

  • 编辑:为什么在局部变量上这么快?(~16秒进行相同的迭代,但对函数内部的局部变量进行迭代)

  • 问题内容: 考虑以下 示例 脚本: 重定向作为文件描述符3的输入的目的是什么?至少在中,如果省略,似乎没有什么区别。如果在非shell中执行它,是否有效果? 更新 对于那些想知道它来自哪里的人,它是Debian 脚本的简化示例。 问题答案: 此处的明确意图是通过确保其stdin来自其他位置来防止从流中读取。 如果没有看到重定向或不重定向的行为差异,那是因为在测试中实际上没有从stdin读取数据。

  • 问题内容: 我了解Scanner的优点,以及何时使用Scanner和BufferedReader。我读了一个不同的问题,但在一些类似的问题中,它的问题是Scannervs. BufferedReader 当我从输入中读取内容时,为什么Scanner这么慢? 我认为这与Scanner中有一个小的缓冲区有关,但是在这里我迷路了。最初的问题来自 Codechef,但我对该解决方案不感兴趣。 这是具有给定

  • 如果我有时运行这些程序,它会在打印“玩家赢”或“玩家输”后继续运行,我可以找到原因。。 这里的输出: 球员滚轴3 2=5 分数是5 玩家滚轮6 4=10 游戏者滚轴6=12 玩家滚轮5 5=10 球员滚轴12=3 球员滚轴1 3=4 球员获胜 球员滚轴4 6=10 球员滚轴4 1=5 构建成功(总时间:0秒)

  • 我明白扫描仪有什么好处,也明白什么时候使用扫描仪,什么时候使用Bufferedreader。我读到了一个不同的,但在一些类似的问题扫描器vs.BufferedReader null