SwiftのOptionalのオーバーヘッド
気になることがあってOptionalのunwrapのオーバーヘッドを調べてみました。
先に結論
- 参照型のunwrapはパフォーマンスが低下する
- 値型のunwrapはあまりパフォーマンスは低下しない
方法
Counter
という型のcount
を10,000,000回インクリメントするのを10回平均するコードを書いて、
アプリの起動時に計測させるようにしました。
Optionalな参照型の場合
class Counter { var count: Int = 0 } let n = 10 var sum: TimeInterval = 0 for _ in 0..<n { let now = Date() let counter: Counter? = Counter() for _ in 0..<10000000 { counter?.count += 1 } sum += -now.timeIntervalSinceNow } let ave = sum / Double(n) print(ave)
結果: 0.248754590749741[秒]
counter
のOptionalを外してみました。
該当箇所だけ書きます。
let counter: Counter = Counter() for _ in 0..<10000000 { counter.count += 1 }
結果: 0.0492702841758728[秒]
かなり違います。
ちなみにforce unwrapでも遅いです。
let counter: Counter! = Counter() for _ in 0..<10000000 { counter.count += 1 }
結果: 0.234673696756363[秒]
Optionalな値型の場合
ほぼ同じコードで、Counter
をstruct
にしてみます。
struct Counter { var count: Int = 0 } let n = 10 var sum: TimeInterval = 0 for _ in 0..<n { let now = Date() var counter: Counter? = Counter() for _ in 0..<10000000 { counter?.count += 1 } sum += -now.timeIntervalSinceNow } let ave = sum / Double(n) print(ave)
結果: 0.0521551012992859[s]
速いです。
Optionalを外してみます。
var counter: Counter = Counter() for _ in 0..<10000000 { counter.count += 1 }
結果: 0.0496872007846832[s]
あまり変わらないです。