前回のエントリが結局フレームワークの話になってしまったため、新しいエントリを書きました。
同じような処理をさせた場合、どの言語が一番早いのか。非常に気になるところでありますが、試したことがありませんでした。今回試してみたところ、意外な結果が出たのです。
下の方に書いたそれぞれのプログラムを実行した結果の、プログラム内部で計測したミリ秒を比較してます。
PHP | Ruby | Python |
---|---|---|
2.80秒 | 0.36秒 | 0.93秒 |
3回計測した平均です。同じ処理をさせるプログラムを書いたつもりですが、本当にフェアなものになっているのか正直自信がありません。そもそもPHPはWebアプリを主な目的としているとのことなので、こういう処理は得意としていないのかもしれない。
また、それぞれのプログラムのループ内2行目、文字列連結の部分をコメントアウトして実行してみると、これまた意外な結果が出ました。
PHP | Ruby | Python |
---|---|---|
0.07秒 | 0.06秒 | 0.39秒 |
PHPは文字列連結が苦手なんだろうか。暗黙的な型変換にコストがかかるのだろうか、等々考えてしまいます。それとも秒を求める部分がネックなんですかね。その辺は今後追っていきます。
ただ、これまでPythonの方がRubyより早い、と思っていたために自分の無知さに猛烈に恥ずかしい思いをしています。
実際にMySQLと連携するバッチを書いたときにはRubyの方が遅かったり、Railsアプリがもっさりだったり、「速い」という印象がまったくありませんでした。が、それはある特定の面しかみていない上での思い込みだったのかもしれません。
これはRailsが遅いのか、もしくはMySQL/Rubyが遅いのか。当時の書き方がマズかったのか。今後、いろんなケースでこういった比較をしてみようかと。
今回の検証がすべてではないし、これが答えだとも思っていません。また、そういう意図を含んだエントリではありません。今回の検証だって、特定の面しか見ていません。が、あまりに意外な結果だったため、自戒の念を含めてブログに書きました。
「こう書くともっとフェアだよ」「こういうテストの方がいいんじゃない」等、アドバイスいただけるとうれしいです。
フレームワークまで含めた検証した方が現実的なのだろうか。。。
PHP
#!/usr/bin/php
<?
function microtime_float()
{list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);}
$_start = microtime_float();
$_sec = date(‘s’);for($i=1;$i<100000;$i++)
{$_val = (mt_rand(0, 100) + $i) / $i;
$_str = $_val.date(‘s’);}
echo microtime_float() – $_start;
?>
Ruby
#! /usr/local/bin/ruby
i=1
_start = Time.now99999.times do
_val = rand(100) / i
_str = _val.to_s + Time.now.sec.to_s
i += 1end
p (Time.now – _start).to_f
Python
#!/usr/bin/python
# -*- coding: utf-8 -*-
import datetime
import random_start = datetime.datetime.now()
for i in range(1, 100000):
_val = random.randint(0, 100) / i
_str = str(_val) + str(datetime.datetime.now().second)print datetime.datetime.now() – _start
検証環境
CPU:Xeon 1.86GHz
メモリ:2GB
OS: CentOS5.4 32bit
PHP:5.2.11
Ruby:1.8.7
Python:2.5.2