Perl, Python, PHPのベンチマークを計測しました

Perl, Python, PHPのベンチマークを計測しました。

=====
1. 環境 及び シナリオ

  1. 実行環境
  2. 実行環境は以下である。
    Platform: Linux(CentOS 5.6)  @sakura VPS
    Memory: 512 MB
    CPU: 仮想2Core

  3. プログラミング言語
  4. 実行・考察を行うプログラミング言語はLAMP構成として通常扱われるスクリプト言語の以下を使用する。
    ・Perl
    ・Python2.4
    ・PHP5.2

  5. 実施シナリオ
  6. No. 演算 概要
    1 i = i + 1 加算
    2 i = i – 1 減算
    3 i = i * i 乗算
    4 i = i / 3 除算
    5 i = i % 3 剰余
    6 s = “Hello,World!” 文字列代入
    7 i = len(string) 文字列数
    8 s = random() ランダム(指定なし)
    9 s = random(1, 100) ランダム(指定あり)
    10 IF (s = “Hello,World!) 文字列判断
    11 IF (i = 5) 数値判断
    12 IF (i = TRUE) Bool値判断
    13 IF文ネスト 条件分岐ネスト
    14 Switch文 ループ(Switch)
    15 While文 ループ(While)
    16 For文 ループ(For)
    17 Foreach文 ループ(Foreach)
    18 print “Hello, World!” 文字列出力
    19 関数呼び出し 関数
    20 File Open, Close オープン, クローズ
    21 File read 1行毎の読み込み
    22 File Write 1行毎の書き込み

    実行時のループ回数は、10000000回ループさせる。但し、実行に時間の掛かり過ぎるシナリオ等に関しては回数を減らす事とする。例外シナリオは以下である。
    No.17: 100000回 PHPにおいて例外が発生する為。
    No.18: 10000回 標準出力に文字列出力する為、処理
    対象のprint文の計測が行いづらい為。

  7. 実施前考察
  8. 本レポートで実行対象となるプログラミング言語はそれぞれ実績のある言語であり、Webサービス開発においてよく使用されている。私はPerl, PHPの経験はあるがPythonは今回が初めての使用となる。
    Perlは全体的に処理が速く、ファイル操作に長けているイメージがある為、全般的にPerlのパフォーマンスが良いと考えている。
    PHPは全体的に処理が遅いイメージがある。特にrandom()やファイル操作が遅いイメージがある。
    Pythonを使用するのは今回が初めてである為、あまりイメージが出来ないが、処理速度的にはPerlと同様の計測値となると予測する。

    よって、 ほぼ全シナリオでPerl < Python < PHP の順番で処理コストが高くなると考える。

  9. 実施方法
  10. 以下の要領で実施を行う。

    1. プログラミング言語毎に22個のプログラムを作成する。
    2. 実施シナリオ毎のアルゴリズムは同一とする。実行時間計測アルゴリズムに関しては後述する。
    3. 言語によっては命令が存在しないケースがある為、その場合は代替(同等)機能を使用する。No.16のPythonにおけるFor文等。
    4. Perlに関しては、ミリ秒単位を取得する組み込み関数がない為、Time::Hiresモジュールを使用する。
    5. シナリオ毎に10回実行し、実行結果として平均値を記録する。その際のコマンドは以下ように実行する。(以下はPythonでの例)
      # loop=1; while [ $loop -le 10 ]; do loop=`expr $loop + 1`; ./check1.py >> result/check1; done;
    6. eの実行結果から平均値を出力するスクリプトを実行し、平均値を得る。平均値出力スクリプトは以下である。
      ====
      #! /usr/bin/perl
      open(IN, $ARGV[0]);
      while (<IN>) {
      $total += $_;
      $count++;
      }
      close(IN);
      print $total / $count . “n”;
      ====
  11. 実行時間計測方法とサンプルコード
  12. 言語毎の実行時間計測は以下のように行う。

    以下では、各言語のシナリオ1のプログラムである。

    Perl
    ====
    #!/usr/bin/perl
    use Time::HiRes;

    my $starttime = Time::HiRes::time;
    for($i=0; $i<10000000; $i++) {
    }
    my $looptime = Time::HiRes::time – $starttime;
    my $starttime = Time::HiRes::time;

    my $j=0;
    for(my $i=0; $i<10000000; $i++) {
    $j = $j + 1;
    }
    print Time::HiRes::time – $starttime – $looptime . “n”;
    ====

    Python
    ====
    #!/usr/bin/python
    import time

    starttime = time.clock()
    for i in range(10000000):
    pass

    looptime = time.clock() – starttime
    starttime = time.clock()

    j = 0
    for i in range(10000000):
    j = j + 1

    print time.clock() – starttime – looptime
    ====

    PHP
    ====
    <?php
    $starttime = microtime(true);
    for($i = 0; $i<10000000; $i++) {
    }
    $looptime = microtime(true) – $starttime;
    $starttime = microtime(true);

    $j=0;
    for($i=0; $i<10000000; $i++) {
    $j = $j + 1;
    }
    echo microtime(true) – $starttime – $looptime . “n”;
    ?>
    ====

2. 実行

  1. 実行結果
  2. 以下が実行結果である。シナリオ毎に最も良いタイムに橙色にしている。また、特徴的な値となった結果は赤色とし、次項以降で考察を行う。なお、単位は全て”秒”である。

    演算 Perl Python PHP
    i = i + 1 0.8 1.04 0.44
    i = i – 1 0.81 1.13 0.45
    i = i * i 0.82 1.3 0.46
    i = i / 3 0.74 1.56 0.73
    i = i % 3 0.84 1.47 0.5
    s = “Hello,World!” 0.87 0.65 0.93
    i = len(string) 1.12 1.64 1.8
    s = random() 0.22 2.05 1.73
    s = random(1, 100) 0.95 27.65 2.86
    IF (s = “Hello,World!) 0.89 0.51 0.78
    IF (i = 5) 0.94 0.49 0.44
    IF (i = TRUE) 0.97 1.08 0.37
    IF文ネスト 0.60 2.05 1.67
    Switch文 251.03 2.81 2.01
    While文 1.13 1.64 0.77
    For文 0.67 1.18 0.91
    Foreach文 0.02 0.01 0.06
    print “Hello, World!” 1.2 0.47 0.96
    関数呼び出し 1.74 1.52 1.56
    File Open, Close 69.01 61.46 80.04
    File read 2 1.46 3.54
    File Write 2.02 4.94 23.18

3. 考察

実行前の考察では、全てのシナリオでPerlが優位だと考えていたが、結果は異なっていた。
この考察としてはPerlの時間計測用の関数において、ミリ秒単位で計測が出来なかった為、
Time::Hiresモジュールを使用した事が影響している可能性がある。
但し、Perlならではの優位性が示されているシナリオもある為、現状のまま考察を進める事とする。

  1. randint()
  2. Pythonのrandint()が非常に遅い結果となった。Perlと比較すると約27倍の差である。調査したところ、Perl, PHPのrand()は組み込み関数であるのに対し、Pythonのrandint()は標準モジュールでの提供であった。
    また、randint()よりもchoice()を使用した方が速いとの情報があった為、変更し実行計測したところ、
    27.65 → 12.36 と半分以下の実行結果となった。但し、Perl, PHPと比較するとまだ遅い結果であった。
    この事からC等で記述される組み込み関数はやはり速いということが分かった。

  3. switch文
  4. Perlのswitch文が異常な程、遅い結果となった。これはPerlには組み込みでswitch文がない為、標準モジュールのSwitchを使用した事が影響していると考えられる。最速であったPHPと比較するとその差は100倍である。
    3.1のrand()と同様に以下に組み込み機能が速いかを再認識させられた。

  5. File操作
  6. 実行前の考察よりPHPはファイル操作が不得意であると考えていたが、その通りの結果であった。特にfopen(), fclose(), fwrite()のパフォーマンスが悪かった。
    また、ファイル操作はPerlが非常に有利だと考えていたが、Pythonが健闘している。

  7. その他
  8. シナリオ毎の実行結果の色付けを確認すると、PHP列に橙色が多く付いている。PHPは全般的に処理が遅いと考えていたが、結果から見ると異なっていた。以前の経験ではPHPのrandom()は遅いと感じていたが、やはりPerlと比較すると倍以上の差が出ていた。(Pythonとの比較に関しては、3.1を参照の事)

  9. 最後に
  10. それぞれのプログラミング言語には高速化技術が存在する。例えば、Perl: mod_perl, Python: mod_wsgi, PHP: APC, eAcceralator等である。これらの技術を使用すれば、より良いパフォーマンスが出やすいが、その前段階として、言語毎の特徴を押さえた上でプログラミング言語の選択や処理ロジック, アルゴリズムを組んでいく必要がある。

=====

おわりです。