iOSのプログラムを書く場合にはインクリメントは変数の前(プリインクリメント、pre-increment)、後ろ(ポストインクリメント、post-incremnt)のどちらの方が高速なのかについてちょっと気になったので調べてみました。
環境は現行のXcodeでデフォルトの設定でビルドした場合。
細かいコンパイラの情報を書くとこんな感じ。
Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn) Target: x86_64-apple-darwin11.3.0 Thread model: posix
ソースコードはこんな感じ。
これのアセンブリがどの様になるかを比較してみました。
Xcodeの場合はココの黒い四角が並んだアイコンをクリックして表示されるメニューから「Assembly」を選択すると簡単に .m ファイルをアセンブリに変更してくれます。
その結果がこちら。アセンブリが読めない人でもラベル名(ジャンプ処理の時に飛び先として使うもの)と .loc で記述してある元ファイルでの行番号くらいしか違いが無く、実際の処理部分については全く同じ記述になっているのが確認出来るかと思います。
LBB1_1: movs r0, #10 movt r0, #0 ldr r1, [sp, #64] cmp r1, r0 bge LBB1_4 .loc 1 29 9 Ltmp6: ldr r1, [sp, #64] movw r0, :lower16:(L__unnamed_cfstring_-(LPC1_5+4)) movt r0, :upper16:(L__unnamed_cfstring_-(LPC1_5+4)) LPC1_5: add r0, pc blx _NSLog Ltmp7: .loc 1 28 21 ldr r0, [sp, #64] adds r0, #1 str r0, [sp, #64] b LBB1_1 LBB1_4: movs r0, #0 movt r0, #0
LBB1_5: movs r0, #10 movt r0, #0 ldr r1, [sp, #64] cmp r1, r0 bge LBB1_8 .loc 1 32 9 Ltmp9: ldr r1, [sp, #64] movw r0, :lower16:(L__unnamed_cfstring_-(LPC1_6+4)) movt r0, :upper16:(L__unnamed_cfstring_-(LPC1_6+4)) LPC1_6: add r0, pc blx _NSLog Ltmp10: .loc 1 31 21 ldr r0, [sp, #64] adds r0, #1 str r0, [sp, #64] b LBB1_5 LBB1_8: movs r0, #0 movt r0, #0
取り敢えず、iOSのプログラムをしている時はインクリメントの位置は特に気にする必要は無いみたいです。
(追記)
このパターンだとこの様な結論になりましたが変数がループのカウンターじゃなくて x = ++i; や x = i++; って使い方ならどうなるかも気になったのでそれは次回のブログネタにします。
関連情報
C++のイテレータだと一時オブジェクトの準備が必要な分だけポストインクリメントの方が遅いみたいです。
preインクリメントとpostインクリメントのコストの違い - Seasons.NET
http://d.hatena.ne.jp/Seasons/20080527/1211911965