比较wc和Smalltalk之间的换行计数速度

时间:2011-11-07 18:06:26

标签: performance smalltalk pharo

我正在比较性能以读取包含文件的行数。

我首先使用wc命令行工具:

$ time wc -l bigFile.csv
1673820 bigFile.csv

real    0m0.157s
user    0m0.124s
sys     0m0.062s

然后在一个干净的Pharo Core Smalltalk最新1.3

| file lineCount |
Smalltalk garbageCollect.
( Duration milliSeconds: [ file := FileStream readOnlyFileNamed: 'bigFile.csv'.
lineCount := 0.
[ file atEnd ] whileFalse: [
    file nextLine.
    lineCount := lineCount + 1 ].
file close.
lineCount. ] timeToRun ) asSeconds. 
15

如何加快Smalltalk代码加速或接近wc性能?

2 个答案:

答案 0 :(得分:8)

[ (PipeableOSProcess waitForCommand: 'wc -l /path/to/bigfile2.csv') output ] timeToRun.

上述报告~207毫秒,其中报告时间:

real    0m0.160s
user    0m0.131s
sys     0m0.029s

我在开玩笑,但也很认真。无需重新发明轮子。 FFI,OSProcess,Zinc等提供了充足的机会来利用几十年来经过实战考验的UNIX实用程序。

如果你的问题更多是关于Smalltalk本身,那么一个开始就是:

[ FileStream 
    readOnlyFileNamed: '/path/to/reallybigfile2.csv'
    do: [ :file | | endings count |
        count := 0.
        file binary.
        file contents do: [ :c | c = 10 ifTrue: [ count := count + 1 ] ].
        count ]
] timeToRun.

这会让你降到2.5秒:

  • 使流二进制保存〜10秒
  • readOnlyFileNamed:do:saved ~1 second
  • 手动查找行结尾而不是使用#nextLine保存~4秒

一个清洁工,但是1/2秒的操作时间是:

file contents occurrencesOf: 10.

当然,如果需要更好的性能,并且您不想使用FFI / OSProcess,那么您将编写一个插件。

答案 1 :(得分:1)

如果你能负担得起在内存中读取整个文件,那么最简单的代码就是

[ FileStream 
    readOnlyFileNamed: '/path/to/reallybigfile2.csv'
    do: [ :file | file contents lineCount ]
] timeToRun.

这将处理LF(Linux),CR(旧Mac),CR-LF(您的名字)的动物园。 Sean的代码只处理LF,成本大致相同。 对于这样的基本操作,我想说Smalltalk vs C的因子是10,所以我怀疑你在不添加自己的原语的情况下获得更高的效率。