・同じ比較方法の場合、if文よりも三項演算子の方がやや速い
・もっとも高速な方法は論理和を使う方法
・もっとも時間がかかる方法は型比較をif文で行う方法
・null比較、型比較で三項演算子を利用すると真偽によって速度が(割と)変わる
( 変数の存在を確認する方法と速度比較(その2) – blog.katsuma.tv)
五年前の記事なのだけれど、関数に渡ってきた引数を存在チェックするとき、どう書くのが早いだろう?という実験レポート。
このレポートによると、
var ret; if(arg) { ret = arg; } else { ret = 'bar'; }
という比較的普通のコードと比べて
var ret = (arg!=null)? arg : 'bar';
三項演算子を使うと倍近く早いらしい。
でも、変数の初期化だったら僕はこう書くことが多い。
if(!arg) { arg = 'bar';}
ということで、五年経った現状と、僕のコードどうなんだろう、というのを見たいと思ったので試してみた。
Google Chrome 26.0.1410.65
[checkStrTernary] 1786 [checkStrIf] 1786 [checkArgsLogicalAdd] 49 [checkArgsTernary] 45 [checkArgsIf] 51 [checkArgsIf2] 48 [checkNullTernary] 74 [checkNullIf] 59 [checkTypeTernary] 61 [checkTypeIf] 48
待てw
やるんじゃないかとは思っていましたが、実質的に何もしていないことを見ぬいて最適化された結果、Date()の分解能テストと化しています。たぶんループが丸ごと削除されていますね。
もちろん、checkStrTernaryとcheckStrIf以外の順位は実施のたびに入れ替わりますので、個別のコードの有利不利を判定することはできません。
FireFox 17.0.1
[checkStrTernary] 14555 [checkStrIf] 14263 [checkArgsLogicalAdd] 10572 [checkArgsTernary] 10674 [checkArgsIf] 11215 [checkArgsIf2] 11258 [checkNullTernary] 10659 [checkNullIf] 10750 [checkTypeTernary] 11102 [checkTypeIf] 11714
うむ。さすが高機能JavaScript開発環境(僕命名)。
これを見ていると、やっぱりcheckStrTernaryとcheckStrIfが遅いものの、あとはそれほど大きな差じゃない程度になっています。checkArgsIfとcheckArgsIf2などは実施のたびに早いほうが入れ替わるので、誤差の範囲内です。
InternetExplorer 9.0.8112.16421
ログ: [checkStrTernary] 11868 ログ: [checkStrIf] 11766 ログ: [checkArgsLogicalAdd] 8618 ログ: [checkArgsTernary] 8525 ログ: [checkArgsIf] 10521 ログ: [checkArgsIf2] 10767 ログ: [checkNullTernary] 10777 ログ: [checkNullIf] 10655 ログ: [checkTypeTernary] 11507 ログ: [checkTypeIf] 10584
おおむねFireFoxと同じ傾向が出ています。よほど変な書き方をしない限り大差ないということですね。
所感
近年のブラウザにおいては、最適化が進んだ結果、以前ほど三項演算子有利ではなくなってきました。
それでも1割程度の差がつくので、シビアな場面ではトライする価値があるかもしれないですが、普通にコード書くときは、読みやすいほうを使うのでいいんじゃないかなーと思いました。