«前の日記(2013-12-31 (Tue)) 最新 次の日記(2015-05-01 (Fri))»

ありし日の気分(改)

2002|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|09|10|11|12|
2011|01|02|03|04|05|06|07|10|11|12|
2012|02|03|04|07|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|12|
2015|05|06|
2018|02|03|08|09|12|
2019|10|
2014年
12月
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
昨日のカウンタ:
今日のカウンタ:

[RDF]

最近のトラックバック

2014-12-28 (Sun)

[iOS] Objective-CとSwiftの速度比較

SwiftとObjective-Cの速度比較をすると、Swiftの方が速かったり遅かったりします。どういう時にSwiftの方が速いのかがわかれば、速いコードを生成する方法もそこからわかると思って簡単な例から速度の比較をしています。 例えばこんな例。長さ1000000のInt型(Objective-CではNSInteger型)の配列を用意して簡単な計算結果を書き込んでいきます。


ObjC:

- (void) clear:(NSInteger)val {

  for (int i = 0; i < 1000000; i ++) {

    array[i] = i & val;

  }

}

Swift:

mutating func clear(val : Int) {

  for i in 0 ..< 1_000_000 {

    array[i] = i & val

  }

}

arm64でビルドしてiPhone6で速度比較をしてみるとこんな感じみたいです。


2014-12-28 13:11:46.278 ASMTest[14858:3959193] swift: 0.00826001167297363

2014-12-28 13:11:46.296 ASMTest[14858:3959193] objc: 0.0162650346755981

順序を入れかえてもこんなもんの数値なので有意に速度が違うんでしょうかね。

コンパイル結果のアセンブリコードを眺めてみるとこんな感じみたいです。 先ずはObjective-Cの場合。


ObjC:

LBB1_1:

	and	x11, x8, x2  // x8がi, x2がval

	str	x11, [x9, x8, lsl #3]  // 配列arrayに計算結果を書込み (x9がarrayのアドレス)

	add	x8, x8, #1  // i += 1

	cmp	x8, x10  // iと1000000の比較

	b.ne	LBB1_1

素直なコードです。(この箇所を特定するのはあんまり素直じゃないですが)

ではSwiftの方はどうかと言うと


Swift:

LBB0_1:

	and	x25, x24, x20  // x24がi、x20がval

	add	x24, x24, #1  // i += 1

	str	x25, [x21, x22]  // 配列arrayに計算結果を書き込み (x21がarray中身のアドレス)

	add	x22, x22, #8  // array中身先頭からのオフセット

	cmp	x24, x23  // iと1000000の比較

	b.ne	LBB0_1

という具合で変数iを格納するレジスタ(x24)と配列先頭からのオフセット用のレジスタ(x22)を分けているぐらいが、Objective-C側との違いぐらいなものです。 実際にはSwift側では、読みにくくなるので上のコードからは削っていますが、_swift_retainとか__swift_isUniquelyReferencedとかってのをループ内で呼び出したりしています。 どうしてそれでここまで速度に差が出るのやら、正直よくわかりませんでした。orz

という具合でしまりのない記事でした。でもSwiftってObjective-Cに比べて遅いと思われてるかも知れないけど、そんなことないんですよってことはわかると思います。(ぉぃ)

そんなこんなで私も書かせて頂きました「開発のプロが教える Swift標準ガイドブック」がクリスマスに発売となりました。 Objective-Cの経験のある方ならSwift書くときにどういう風に考えるかなー、どこでつまづくかなーって考えて、話し合って書いていきました。 Objective-CにはないGenericとかOptionalについても(私の執筆箇所じゃないですが)わかりやすく書けていると思います。 structやclassのつまづきやすいところもけっこうネチネチ調べて書いていますので、中級者以上の方も何かしら新しい発見があるのではないかと思います。 年末年始の休みのお供にぜひお買い求め下さい。

amazonのページはこちらです。



C++でつくるUnreal Engineアプリ開発 for Windows & macOS  UE4でC++を使う方法を書いた本です。

«前の日記(2013-12-31 (Tue)) 最新 次の日記(2015-05-01 (Fri))»


2002|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|09|10|11|12|
2011|01|02|03|04|05|06|07|10|11|12|
2012|02|03|04|07|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|12|
2015|05|06|
2018|02|03|08|09|12|
2019|10|