我正在比较性能以读取包含文件的行数。
我首先使用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性能?
答案 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秒:
一个清洁工,但是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,所以我怀疑你在不添加自己的原语的情况下获得更高的效率。