強火で進め

このブログではプログラム関連の記事を中心に書いてます。

iOSのプログラムを書く場合にはインクリメントは変数の前、後ろどちらの方が高速?(その1)

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