等価演算子(==)と厳密等価演算子(===)

以下は間違っているのでこれを参照して下さい。

高速化 - uupaaの開発日記で高速化について書いてあった。最初のfor文の長さの参照とインクリメントの話とループ展開は知っていたけど、厳密比較演算子も速くなるというのは初めて知った。演算子にそんなに違いはないと思っていたけど、冷静に考えると、比較回数が少ないという記事の意見は正しい気がする。というわけで、実際にベンチ取ってみた。

下のベンチマークはプリミティブ値同士のチェックしか行っていないので、等価演算子と厳密等価演算子 in ECMA-262 3rd Edition - 0x集積蔵を参照のこと。というか、今、ベンチ取ったら、やっぱり、厳密等価演算子の方が速いんだが。ベンチ取ったマシンがVistaだったから良くなかったのかなぁ。

結論

JavaScriptでは厳密等価演算子は若干遅いので必要なところで使うべき。むしろ、IEでは文字列などを一時変数に入れるとかした方が劇的に速くなる。Fxでは遅くなったけど。

ベンチマーク

function write() {
	var str = [];
	for (var i = 0, j = arguments.length; i < j; ++i)
		str[i] = arguments[i];
	document.write(str.join(' ') + '<br>');
}

var arr = [];
for(var i=0;i<150000;i++)arr[i]=Math.ceil(Math.random()*6); // 1〜6の乱数を生成

write("*数字の配列を操作");
(function (arr) {
	write("比較演算子1-1");
	var d=new Date;
	for(var i=0,j=arr.length;i<j;++i)arr[i]==6;
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子1-2");
	var d=new Date;
	for(var i=0,j=arr.length;i<j;++i)arr[i]===6;
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子2-1");
	var d=new Date;
	for(var i=0,j=arr.length,a=6;i<j;++i)arr[i]==a;
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子2-2");
	var d=new Date;
	for(var i=0,j=arr.length,a=6;i<j;++i)arr[i]===a;
	write((new Date)-d);
})(arr.concat());

write("*文字列の配列を操作");
for(var i=0,j=arr.length;i<j;i++)arr[i]=""+arr[i];
(function (arr) {
	write("比較演算子1-1");
	var d=new Date;
	for(var i=0,j=arr.length;i<j;++i)arr[i]=="6";
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子1-2");
	var d=new Date;
	for(var i=0,j=arr.length;i<j;++i)arr[i]==="6";
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子2-1");
	var d=new Date;
	for(var i=0,j=arr.length,a="6";i<j;++i)arr[i]==a;
	write((new Date)-d);
})(arr.concat());

(function (arr) {
	write("比較演算子2-2");
	var d=new Date;
	for(var i=0,j=arr.length,a="6";i<j;++i)arr[i]===a;
	write((new Date)-d);
})(arr.concat());

IE7

*数字の配列を操作
比較演算子1-1
206
比較演算子1-2
211
比較演算子2-1
211
比較演算子2-2
208
*文字列の配列を操作
比較演算子1-1
513
比較演算子1-2
420
比較演算子2-1
254
比較演算子2-2
259
*数字の配列を操作
比較演算子1-1
198
比較演算子1-2
207
比較演算子2-1
217
比較演算子2-2
212
*文字列の配列を操作
比較演算子1-1
388
比較演算子1-2
436
比較演算子2-1
253
比較演算子2-2
256
*数字の配列を操作
比較演算子1-1
204
比較演算子1-2
211
比較演算子2-1
208
比較演算子2-2
214
*文字列の配列を操作
比較演算子1-1
387
比較演算子1-2
434
比較演算子2-1
264
比較演算子2-2
254

Fx3

(配列の長さは1000000に変更)

*数字の配列を操作
比較演算子1-1
256
比較演算子1-2
262
比較演算子2-1
265
比較演算子2-2
278
*文字列の配列を操作
比較演算子1-1
269
比較演算子1-2
283
比較演算子2-1
303
比較演算子2-2
277
*数字の配列を操作
比較演算子1-1
263
比較演算子1-2
259
比較演算子2-1
263
比較演算子2-2
287
*文字列の配列を操作
比較演算子1-1
262
比較演算子1-2
280
比較演算子2-1
307
比較演算子2-2
352
*数字の配列を操作
比較演算子1-1
260
比較演算子1-2
265
比較演算子2-1
263
比較演算子2-2
280
*文字列の配列を操作
比較演算子1-1
269
比較演算子1-2
291
比較演算子2-1
304
比較演算子2-2
283

感想

ベンチの取り方がまずいのかもしれないが、どう見ても速いとは言えない。JavaScriptにおいては、なんらかの最適化で等価演算子の方が速く処理できるようだ。むしろ、正直誤差の範囲程度の比較演算子よりも、文字列比較の時、IEなら比較する値は一時変数に入れるとすごく速くなり、Fxだと逆に遅くなるってことを知って、驚いた。