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

Jua*_*rre 5 performance smalltalk pharo

我正在比较读取多少行包含文件的性能.

我首先使用wc命令行工具完成了它:

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

real    0m0.157s
user    0m0.124s
sys     0m0.062s
Run Code Online (Sandbox Code Playgroud)

然后在一个干净的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
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*ris 8

[ (PipeableOSProcess waitForCommand: 'wc -l /path/to/bigfile2.csv') output ] timeToRun.
Run Code Online (Sandbox Code Playgroud)

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

real    0m0.160s
user    0m0.131s
sys     0m0.029s
Run Code Online (Sandbox Code Playgroud)

我在开玩笑,但也很认真.无需重新发明轮子.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.
Run Code Online (Sandbox Code Playgroud)

那会让你降到2.5秒:

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

一个更干净,但1/2秒更长的操作将是:

file contents occurrencesOf: 10.

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