単純ファイル集計の各言語ベンチマーク


いろんな言語でファイルを単純に集計するという処理のベンチマークをとってみました。


処理はタブ区切りのkey-valueの羅列のファイルからkeyごとにvalueを合計するというモノ。
但し家で環境もないのでだいたいcygwinの結果です。
Javaだけ素で動くからちょっと有利な結果になってるのかも。

Language Version Src[Byte] Src[line] 100000行[s] 1000000行[s] 10000000行[s]
gawk 3.1.6(cygwin) 108 9 0.229 1.634 15.552
Python 2.5.2(cygwin) 277 12 0.634 4.644 47.492
Java 1.6.0_22-b04 1046 24 0.83 7.027 46.492
Perl v5.10.0(cygwin) 141 8 1.395 12.755 129.764
Ruby 1.8.7(cygwin) 243 14 1.928 19.656 192.643


<グラフとか追加したい>


単純処理はgawkが速いようです。(一般的にはあまり言語と思われてないのかな?)
件数がもうちょっと行くと、おそらくJavaPythonに勝ちそうです。
※だいぶUpdateしてないのでバージョン古めかもしれません。ck使えなくなると嫌なので


ソースの量も比較したかったので、けっこう詰めて端折って書いています。## マネしないでね
以下、ソース。



gawk

#!/usr/bin/awk -f
{
    total[$1]+=$2
}
END{
    for(key in total){
        print key"\t"total[key]
    }
}


Perl

#!/usr/bin/perl
while(<>){
    @rec = split();
    $table{$rec[0]} += $rec[1];
}
for $key(keys(%table)){
    print "$key\t$table{$key}\n";
}


Python

#!/usr/bin/env python
import sys
total={}
for line in open(sys.argv[1], 'r'):
    items=line[:-1].split('\t')
    if items[0] in total:
        total[items[0]]+=int(items[1])
    else:
        total[items[0]]=int(items[1])

for key in total:
    print key+"\t"+str(total[key])


Ruby1.8

#!/usr/bin/ruby
total={}
while a=gets
    a.chomp!
    b=a.split("\t")
    if total[b[0]]==nil
        total[b[0]]=b[1].to_i
    else
        total[b[0]]+=b[1].to_i
    end
end
for key in total.keys
    print key+"\t"+total[key].to_s+"\n"
end


Java

package sample;
import java.io.BufferedReader;
import java.io.File;
import java.util.HashMap;
public class SimpleSum {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new java.io.FileReader(new File(args[0])));
            java.util.Map<String, Integer> map = new HashMap<String, Integer>();
            String line;
            while ((line = reader.readLine()) != null) {
                String[] record = line.split("\t");
                int val = Integer.parseInt(record[1]);
                map.put(record[0], map.containsKey(record[0])?map.get(record[0])+val:val);
            }
            for (String key : map.keySet()) {
                System.out.print(key + "\t" + map.get(key) + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

# 今見ると直せるところいっぱいあるな。。今度直して計りなおしたい。正規表現系とかも。