Swift の Array/Dictionary は最適化なしでコンパイルした場合, 実行速度が遅くなります. NSMutableArray/NSMutableDictionary と比べてもかなり遅い結果となります.
テストコード
この問題をテストするために単純なサンプルコードを作成しました. NSMutableArray と Swift の Array にそれぞれ 1,000,000 個の要素を追加するコードと, NSMutableDictionary と Swift の Dictionary に 100,000 個の要素を追加するコードです.
OS X の Swift は現時点で Beta とされているため, iOS アプリケーションとして作成しました. 利用したコードは GitHub で公開しています.
コンパイルと実行
Xcode でプロジェクトファイルを開き, コンパイルし実行します. アプリ内の Run Benchmark をタップするとテストを実行し, UIAlertView で結果を表示します.
Swift のコンパイラには Xcode 6.0.1 (6A317) の時点で, -Onone (最適化なし), -O (最適化あり), -Ounchecked (最適化あり, 実行時の様々なチェックを行わない) があります. これらの3種類の最適化オプションを切り替えてパフォーマンスを測定します.
-Ofast は Xcode 6 Beta 5 から -Ounchecked に変更されました.
テスト結果
テスト結果は以下のようになりました. 共通の環境は次の通りです: OS X Yosemite (14A329f) / Xcode 6.0.1 (6A317)
iPhone 5s Simulator / iOS 8 (12A365)
Onone
NSMutableArray: 0.32 [sec] Swift Array: 7.02 [sec] NSMutableDictionary: 0.08 [sec] Swift Dictionary: 2.04 [sec]
O
NSMutableArray: 0.11 [sec] Swift Array: 0.06 [sec] NSMutableDictionary: 0.05 [sec] Swift Dictionary: 0.02 [sec]
Ounchecked
NSMutableArray: 0.11 [sec] Swift Array: 0.10 [sec] NSMutableDictionary: 0.05 [sec] Swift Dictionary: 0.02 [sec]
iPhone 5s / iOS 8 (12A365)
Onone
NSMutableArray: 0.80 [sec] Swift Array: 29.15 [sec] NSMutableDictionary: 0.19 [sec] Swift Dictionary: 8.27 [sec]
O
NSMutableArray: 0.14 [sec] Swift Array: 0.28 [sec] NSMutableDictionary: 0.09 [sec] Swift Dictionary: 0.10 [sec]
Ounchecked
NSMutableArray: 0.14 [sec] Swift Array: 0.51 [sec] NSMutableDictionary: 0.10 [sec] Swift Dictionary: 0.10 [sec]
Simulator (x64) と iPhone 5s (arm64) で少し傾向が異なります.
どちらにも共通して言えることは, 最適化なしの場合, Swift の Array と Dictionary は圧倒的に遅く NSMutableArray と NSMutableDictionary に比べて数十倍の時間がかかっています.
最適化を行った場合はアーキテクチャにより傾向が異なり, Intel アーキテクチャの場合は Swift の Array と Dictionary の方が高速に実行でき, NSMutableArray と NSMutableDictionary に比べて約半分の時間で実行できるようになります. しかし, ARM アーキテクチャの場合は Swift の Array と Dictionary の方が遅く NSMutableArray と NSMutableDictionary に比べて約1〜2倍の時間がかかってしまいます.
まとめ
Swift の Array と Dictionary は最適化無しで実行すると非常に遅くなります. しかし, 最適化を行うと Intel アーキテクチャでは NSMutableArray や NSMutableDictionary 約半分の時間で, ARM アーキテクチャでは数倍の時間で実行できるようになります.
実際にアプリケーションを開発する場合, デバッグビルドは最適化なしで行うことが多いですが, Swift でこれを行うと予想以上にパフォーマンスが低下する可能性があります. コンパイル時間は長くなりますが, リリースするものと近いパフォーマンスで実行したい場合は, デバッグビルドでも最適化を行うほうが良さそうです.
今後のアップデートで改善されていくとは思いますが, Apple には Swift の最適化なしでの実行速度の改善と ARM アーキテクチャでの最適化の改善を望みたいところです.
追記: Xcode 6.1 / iOS 8.1 でのテスト結果
Xcode 6.1 と iOS 8.1 が正式リリースとなったため, 改めて iPhone 5s 実機と iPhone 5s Simulator でテストを行いました. 共通の環境は次の通りです: OS X Yosemite (14A388a) / Xcode 6.1 (6A1052d) / iOS 8.1 (12B411)
iPhone 5s Simulator / iOS 8.1 (12B411)
Onone
NSMutableArray: 0.34 [sec] Swift Array: 6.61 [sec] NSMutableDictionary: 0.073 [sec] Swift Dictionary: 2.58 [sec]
O
NSMutableArray: 0.12 [sec] Swift Array: 0.014 [sec] NSMutableDictionary: 0.048 [sec] Swift Dictionary: 0.036 [sec]
Ounchecked
NSMutableArray: 0.12 [sec] Swift Array: 0.014 [sec] NSMutableDictionary: 0.047 [sec] Swift Dictionary: 0.033 [sec]
iPhone 5s / iOS 8.1 (12B411)
Onone
NSMutableArray: 0.88 [sec] Swift Array: 27.9 [sec] NSMutableDictionary: 0.21 [sec] Swift Dictionary: 10.9 [sec]
O
NSMutableArray: 0.14 [sec] Swift Array: 0.029 [sec] NSMutableDictionary: 0.085 [sec] Swift Dictionary: 0.16 [sec]
Ounchecked
NSMutableArray: 0.14 [sec] Swift Array: 0.031 [sec] NSMutableDictionary: 0.088 [sec] Swift Dictionary: 0.15 [sec]
追記: Xcode 6.1 / iOS 8.1 まとめ
Xcode 6.1 と iOS 8.1 では Swift の Array が大きく高速化していることがわかります. 最適化ありの場合 Intel アーキテクチャ, ARM アーキテクチャともに, NSMutableArray よりも数倍〜10倍程度高速になっています.
一方で Swift の Dictionary の速度にはあまり改善が見られないようです. 今後のアップデートでの改善に期待です.