効率比較:各種言語で100 W個の時間オブジェクトを構築する

2984 ワード

もともとperlでは、指定された時間範囲で比較的大きなログファイルをフィルタするように書かれていました.しかし、130 W行のログをフィルタリングするのに2分以上かかり、そのうちのいくつかの低効率関数を単独で効率テストしたところ、100 W個の時間オブジェクトを構築するのにかかる時間も大きな家であることが分かった.
そこで,100 W個の時間オブジェクト(あるいは時間構造)を構成するいくつかの言語の性能を特に比較した.以下は結論です.
  • Perl(Time::Pieceモジュール):13秒
  • Python(timeモジュール):8.8秒(arrowパッケージ:50秒)
  • Ruby(内蔵Timeクラス):2.8秒、タイムゾーンを直接指定すると0.6秒
  • しかかかりません.
  • Ruby(標準ライブラリDateTime):strptimeフォーマットは0.9-1秒で、直接DateTime.newは0.4秒
  • しかかかりません
  • Golang(Timeパッケージ):コンパイル済み0.17秒、コンパイル+実行0.26秒
  • C(time.h):0.042秒
  • 各言語のテストコードを次に示します.
    # Perl(Time::Piece)
    $ time perl -MTime::Piece -e 'for(1..1000000){$t = Time::Piece->strptime("2017-03-23 16:30:15", "%Y-%m-%d %H:%M:%S")}'
    real    0m13.045s
    user    0m11.969s
    sys     0m0.011s
    # Ruby(Time)
    $ time ruby -e '1000000.times {|x| t=Time.new(2017,3,23,16,30,15)}'
    real    0m2.755s
    user    0m1.781s
    sys     0m0.767s
    
    $ time ruby -e '1000000.times {|x| t=Time.new(2017,3,23,16,30,15,"+08:00")}'
    
    real    0m0.685s
    user    0m0.500s
    sys     0m0.203s
    # Ruby(Datetime)
    $ time ruby -r'date' -e '1000000.times {|x| t = DateTime.strptime("2017-03-23 16:30:15", "%Y-%m-%d %H:%M:%S")}'
    real    0m0.994s
    user    0m0.885s
    sys     0m0.036s
    
    $ time ruby -r'date' -e '1000000.times {|x| t = DateTime.new(2017,3,23,16,30,15)}'
    real    0m0.450s
    user    0m0.234s
    sys     0m0.219s
    # Python
    import time
    
    fmt = "%Y-%m-%d %H:%M:%S"
    for i in range(0,1000000):
            time.strptime("2017-10-23 12:30:23", fmt)
    
    $ time python3 a.py
    real    0m8.411s
    user    0m7.805s
    sys     0m0.094s
    # Golang
    package main
    
    import (
            "time"
    )
    
    func main() {
            const format = "2006-01-02 15:04:05"
            for i := 1; i < 1000000;i++ {
                    time.Parse(format, "2018-03-23 16:30:15")
            }
    }
    
    $ time go run a.go       #       go  
    
    real    0m0.267s
    user    0m0.213s
    sys     0m0.070s
    
    $ time ./a         #      go  
    
    real    0m0.176s
    user    0m0.162s
    sys     0m0.001s
    // C
    #define _XOPEN_SOURCE
    #include 
    
    int main(void) {
            struct tm tm;
            int i;
            for(i = 1;i<=1000000;++i){
                    strptime("2017-03-23 16:30:15", "%Y-%m-%d %H:%M:%S", &tm);
            }
            return 0;
    }
    
    $ time ./time.out 
    
    real    0m0.042s
    user    0m0.039s
    sys     0m0.001s

    では、シナリオを書くには、どの言語を使うのでしょうか.ルビーはいい選択だと思いますが、Golangもいい選択だと思います.
    その後、perl/python/rubyの単純なサイクルでの効率を比較してみると、解釈型言語の純計算での優劣となり、pythonの差は遠く、rubyは再びリードした.
    # perl     
    $ time perl -e '$a=0;$i=0;for(1..100000000){$a+=1;}'
    real    0m2.688s
    user    0m2.672s
    sys     0m0.016s
    
    # python     
    [root]$ time python <