JSでi++と++iどっちが速い?

結論から言うと、現在のChromeのみをターゲットにして最適化するという特殊なケースを除き*1どちらでも変わらないといえます。

[追記]

指摘を受けて再考してみました。そもそもjsperfでは初期化コード(今回はdataなどの初期化に使用)は一度しか走らないにもかかわらず、このベンチマークコードではdataの中身を書き換えています。これがスコアに影響を与えていたようです。

data[index] = data[index] * 2data[index] = index * c にした結果はChromeでも安定して双方有意差なしという結果になりました。

http://jsperf.com/postfix-or-pretfix-increment/4

JSのベンチマークの難しさを思い知りました。
[/追記]

http://jsperf.com/prefix-or-postfix-increment*2

上記のjsperfページの下の方に様々なブラウザでの実測ベースの結果があるわけですが、ほとんどのケースでは同じで、Chromeなどの一部の環境ではi++のほうが圧倒的に高速という結果になっています。

普通に考えれば双方同じないし++iのほうが高速になるはずなので、for(;;i++)という形を特別に最適化しているのかもしれませんが、それならそれでfor(;;++i)も同様に最適化はできるはず。この結果はよくわかりません。

そういうわけで、現時点ではfor(;;i++)のほうが高速であるケースが多いと言えます。しかし演算子オーバーロードのないJSでは理論的にはどちらも同じ演算になるように最適化できるはずで*3、i++のほうが高速というのはたまたま今そうであるというだけに過ぎません。また、for以外の用途はまた別でかもしれませんが、最適化可能性は同じなのでやはりどちらでも構わないはずです。

またデバイスやJSエンジンによる差が非常に大きいので、一般論はほとんど無意味です。実行環境がわかった上でclosure compilerのようなプリプロセッサで特定の実行環境向けに最適な形に置換するのはありかもしれません。

もちろんこれはJSに限った話です。C++なら常にfor(;;++i)すべきですよ。

*1:追記参照

*2:このベンチマークおよび以下の説明は不正確。追記参照。

*3:ただし演算がvoid contextであるとき。演算結果を使うケースでは当然事情は異なる。