配列の作成方法による速度の比較
8月 24th
まずはnew Array()を使用した方法です。
function test1 () {
var array = new Array();
}
次に[]を使用して作成します。
function test2 () {
var array = [];
}
この二つの関数を100万回呼び出した時の結果は以下の通りです。
| OS | ブラウザ | バージョン | test1 | test2 |
|---|---|---|---|---|
| Mac OS X | Safari | 5.0 | 0.2848 | 0.2721 |
| Mac OS X | Firefox | 3.6 | 0.1825 | 0.4413 |
| Mac OS X | Chrome | 5.0 | 0.0248 | 0.0143 |
| Windows | Internet Explorer | 8.0 | 1.2156 | 1.0547 |
| Windows | Firefox | 3.6 | 0.1524 | 0.5879 |
| Windows | Chrome | 5.0 | 0.0265 | 0.0146 |
まず、Chromeが優秀すぎます。Mac・Winともに桁違いの速さです。そしてFirefoxだけがtest1の方が速いという結果に。しかもその差はかなりの大きさです。IEは置いといて、Safariが微妙な差で、Chromeが十分に速い事を考えると、これはおとなしくnew Array()を使った方がいいのかもしれません。
Windows: Parallels Desktop 5
整数の絶対値の求め方の比較
8月 15th
まずは普通にMath.abs()を使用した方法です。
function test1 () {
var num = -10;
var a = Math.abs(num);
}
次に条件分岐した場合。
function test2 () {
var num = -10;
var a = num < 0 ? -num : num;
}
最後にビット演算を使用した場合。
function test3 () {
var num = -10;
var a = (num ^ (num >> 31)) - (num >> 31);
}
これらの関数を各種ブラウザで100万回呼び出した時の時間がこちらです。
| OS | ブラウザ | バージョン | test1 | test2 | test3 |
|---|---|---|---|---|---|
| Mac OS X | Safari | 5.0 | 0.0268 | 0.0193 | 0.0164 |
| Mac OS X | Firefox | 3.6 | 0.0171 | 0.0039 | 0.0108 |
| Mac OS X | Chrome | 5.0 | 0.0171 | 0.0091 | 0.0087 |
| Windows | Internet Explorer | 8.0 | 0.7109 | 0.4203 | 0.4750 |
| Windows | Firefox | 3.6 | 0.0140 | 0.0046 | 0.0088 |
| Windows | Chrome | 5.0 | 0.0185 | 0.0120 | 0.0134 |
IEを除いてみんな高速ですので、Math.abs()で良さそうなのですが、より速さを求める人はtest2かtest3の方法をオススメします。小数の絶対値が必要な人はtest2を使ってください。
Windows: Parallels Desktop 5
if 〜 else if の順番による速度比較
8月 11th
まずは可能性の少ないもの順で条件を指定してみます。
function test1 () {
var rnd = Math.random();
var result = 0;
if (rnd < 0.01) {
result = 1;
} else if (rnd < 0.02) {
result = 2;
} else if (rnd < 0.04) {
result = 3;
} else if (rnd < 0.08) {
result = 4;
} else if (rnd < 0.16) {
result = 5;
} else {
result = 6;
}
}
そして可能性の高いもの順で条件を指定してみます。
function test2 () {
var rnd = Math.random();
var result = 0;
if (rnd >= 0.16) {
result = 6;
} else if (rnd >= 0.08) {
result = 5;
} else if (rnd >= 0.04) {
result = 4;
} else if (rnd >= 0.02) {
result = 3;
} else if (rnd >= 0.01) {
result = 2;
} else {
result = 1;
}
}
これら二つの関数を100万回呼び出した際にかかった時間はこちら。
| OS | ブラウザ | バージョン | test1 | test2 |
|---|---|---|---|---|
| Mac OS X | Safari | 5.0 | 0.0384 | 0.0349 |
| Mac OS X | Firefox | 3.6 | 0.0793 | 0.0587 |
| Mac OS X | Chrome | 5.0 | 0.0441 | 0.0349 |
| Windows | Internet Explorer | 8.0 | 3.9332 | 3.2136 |
| Windows | Firefox | 3.6 | 0.2278 | 0.1923 |
| Windows | Chrome | 5.0 | 0.1935 | 0.1382 |
多かれ少なかれtest2の方が高速ですね。可能性の高い事が予想される条件は、上の方に持っていった方が良さそうです。
Windows: Fujitsu FMV Intel Atom CPU Z530 1.6GHz (2GB)
二重引用符内に変数を使用するコスト
8月 10th
まずは簡単な例から。
$animal = "cat";
for ($i=0; $i<1000000; $i++) {
$str = "This is a $animal.";
}
そして二重引用符の外に変数を出してみると・・・。
$animal = "cat";
for ($i=0; $i<1000000; $i++) {
$str = "This is a " . $animal . ".";
}
若干外に変数がある方が速いです。約97%の時間に短縮されました。でもこのくらいなら無視してもイイかもしれませんね。それでは二重引用符内に複数の変数がある場合はどうなるでしょうか?
変数を4つ用意してみました。
$a = "four";
$b = "words";
$c = "needing";
$d = "love";
for ($i=0; $i<1000000; $i++) {
$str = "If I am $a $b then I am $c of your $d";
}
そしてそれを同じように二重引用符の外に置いてみると・・・。
$a = "four";
$b = "words";
$c = "needing";
$d = "love";
for ($i=0; $i<1000000; $i++) {
$str = "If I am " . $a . " " . $b . " then I am " . $c . " of your " . $d;
}
これまた速いは速いんだけど微妙な差ですね。こちらは約94%に短縮です。どうやら変数の個数に比例して速くはなるようですね。もしソースが見にくくならないのなら、変数は二重引用符の外に出しておいた方がイイかもしれません。
PHP: 5.3.1
OS: Mac OS X 10.6.4
Server: MacBook Pro 13インチ 2.66GHz Intel Core 2 Duo (8GB 1,067 MHz)
文字列連結のコスト
8月 9th
まずはシンプルな連結から。
function test1 () {
var str = '';
str += 'こんにちは。';
}
次に文字列を長くしてみました。
function test2 () {
var str = '';
str += 'おはようございます。こんにちは。こんばんは。ありがとうございます。おやすみなさい。';
}
文字列を2つに分割してみました。
function test3 () {
var str = '';
str += 'おはようございます。こんにちは。こんばんは。' + 'ありがとうございます。おやすみなさい。';
}
さらに細かく文字列を分割してみました。
function test4 () {
var str = '';
str += 'おはようございます。' + 'こんにちは。' + 'こんばんは。' + 'ありがとうございます。' + 'おやすみなさい。';
}
最後に分割した文字列を1つずつ連結してみました。
function test5 () {
var str = '';
str += 'おはようございます。';
str += 'こんにちは。';
str += 'こんばんは。';
str += 'ありがとうございます。';
str += 'おやすみなさい。';
}
これらの関数を100万回呼び出した時の時間が以下の通りです。
| OS | ブラウザ | バージョン | test1 | test2 | test3 | test4 | test5 |
|---|---|---|---|---|---|---|---|
| Mac OS X | Safari | 5.0 | 0.021 | 0.020 | 0.225 | 0.343 | 0.926 |
| Mac OS X | Firefox | 3.6 | 0.014 | 0.014 | 0.014 | 0.014 | 1.174 |
| Mac OS X | Chrome | 5.0 | 0.028 | 0.028 | 0.056 | 0.109 | 0.098 |
| Windows | Internet Explorer | 8.0 | 3.304 | 3.273 | 5.588 | 11.358 | 11.767 |
| Windows | Firefox | 3.6 | 0.042 | 0.041 | 0.041 | 0.041 | 3.977 |
| Windows | Chrome | 5.0 | 0.081 | 0.074 | 0.268 | 0.501 | 0.388 |
Firefox以外のブラウザでは連結数を多くするほど遅くなりますね。またFirefoxやSafariでは行を分けて連結すると遅くなってしまうようです。スクリプトの見やすさとの兼ね合いもあると思いますが、無駄に分割して連結している箇所は一つにまとめた方が良さそうです。
Windows: Fujitsu FMV Intel Atom CPU Z530 1.6GHz (2GB)
とある整数が偶数かどうかを判定
8月 9th
一つ目は%(余り)を使った方法。2で割った余りが0なら偶数という考え方です。この関数に数字を投げて、trueならばそれは偶数という事です。
function test1 (num) {
return num % 2 == 0 ? true : false;
}
もう一つはビット演算を使用した方法です。こちらも同じく数字を投げてtrueならば偶数です。
function test2 (num) {
return (num & 1) == 0 ? true : false;
}
上記2つの関数を100万回呼び出した時の時間が以下の通りです。
| OS | ブラウザ | バージョン | test1 | test2 |
|---|---|---|---|---|
| Mac OS X | Safari | 5.0 | 0.227 | 0.179 |
| Mac OS X | Firefox | 3.6 | 0.314 | 0.129 |
| Mac OS X | Chrome | 5.0 | 0.401 | 0.087 |
| Windows | Internet Explorer | 8.0 | 2.652 | 2.059 |
| Windows | Firefox | 3.6 | 0.305 | 0.026 |
| Windows | Chrome | 5.0 | 0.336 | 0.035 |
どのブラウザもビット演算(test2)を使用する方が速いですね。IEが激遅なのは気にしないでおきます。ちなみに判定する数値に小数が含まれる可能性がある場合は、ビット演算の方は小数点以下が切り捨てられますので正確に判定できません。ご注意ください。
Windows: Fujitsu FMV Intel Atom CPU Z530 1.6GHz (2GB)
array_pushと$array[]
8月 8th
まずはarray_pushを使用してみました。メモリの都合上、10万回のリピートです。
$array = array();
for ($i=0; $i<100000; $i++) {
array_push($array, $i);
}
次に$array[]で追加してみます。同じく10万回リピートします。
$array = array();
for ($i=0; $i<100000; $i++) {
$array[] = $i;
}
結果、$array[]の方がarray_pushより1.5倍程度速いです。
PHP: 5.3.1
OS: Mac OS X 10.6.4
Server: MacBook Pro 13インチ 2.66GHz Intel Core 2 Duo (8GB 1,067 MHz)
array_key_existsとisset
8月 8th
最初に使用するデータを準備します。
$array = array();
for ($i=0; $i<100000; $i++) {
$array[$i] = 1;
}
そしてまずはarray_key_existsから。100万回リピートさせてみます。
for ($i=0; $i<1000000; $i++) {
$flag = array_key_exists(1000, $array);
}
次にissetで試してみます。同じく100万回リピートします。
for ($i=0; $i<1000000; $i++) {
$flag = isset($array[1000]);
}
結果、issetの方がarray_key_existsより3.5倍程度速いです。
PHP: 5.3.1
OS: Mac OS X 10.6.4
Server: MacBook Pro 13インチ 2.66GHz Intel Core 2 Duo (8GB 1,067 MHz)