[Xcode 6 / iOS 8] ユニットテストのようにパフォーマンスをテストするんだ!

はじめに
Xcode 6 でユニットテストのようにパフォーマンスをテストする機能が追加されました。
これによって重そうなロジックにパフォーマンスの測定を設定しておき常に計測することができます。
例えば、画像や動画、音声など圧縮データのエンコード/デコード処理、大量のデータをソートする処理、暗号化する処理などが、ざっと思いつく重い処理です。
今回はサンプルとしてログ出力で追加されたprintlnとNSLogのパフォーマンスを比較してみます。
測定してみる
パフォーマンスの測定はユニットテストと同じように扱われますが、Assertがある訳ではなくself.measureBlock()の中で呼び出されたコードが計測対象になります。 新規にプロジェクトを作成するとTestクラスが作成されますが、そこにもself.measureBlock()が作成されるようになりました。
今回必要なソース
テストされるクラス
Logger.swift
class Logger {
let max = 10000</p>
func writeNSLog(){
for var i = 0; i < max; i++ {
NSLog("%d",i)
}
}
func writePrintln(){
for var i = 0; i < max; i++ {
println(String(i))
}
}
}
テストクラス
LoggerTests.swift
import XCTest
class LoggerTests: XCTestCase {
…
func testLoggerPrintln() {
let logger = Logger()
self.measureBlock() {
logger.writePrintln()
}
}
func testLoggerNSLog() {
let logger = Logger()
self.measureBlock() {
logger.writeNSLog()
}
}
}
どうやって計測するのか
ユニットテストと同様にTest Navigatorや⌘+Uで実行可能です。
実行するとテストコードに結果が表示され、テストコードのグレーになった部分をクリックすると詳細が表示されます。
何をどう計測しているのか
10回計測し平均(Average)と標準偏差(STDDEV)を求めています。
標準偏差って
どれだけデータがバラついているか、の指標
標準偏差(ひょうじゅんへんさ、英語: Standard Deviation)は、分散の正の平方根である。統計値や確率変数の散らばり具合(ばらつき)を表す数値のひとつであり、σ や s で表す。例えば、ある試験でクラス全員が同じ点数であった場合(すなわち全員が平均値であった場合)、データにはばらつきがないので、標準偏差と分散は0になる。Wikipediaより
表示項目
- Result: 評価の結果
- Average: 10回計測した時間の平均値
- Baseline: この値を下回ればテスト失敗とみなす
- Max STDDEV: 標準偏差の最大値。この値を上回れば失敗とみなす
評価のさせ方
最初にテストした時点ではResultとBaselineに"No Baseline"と表示されます。Set BaselineボタンをクリックすればBaselineにAverageの値が入り、基準値として設定されます。またEditボタンでBaselineとMax STDDEVは編集可能です。
その上でもう一度計測してみましょう。
すると、Resultに値が入ってきました!
評価の見方
Result: 20.788% better (±17%)
Baselineよりも 20.788% 高速だった。 また、標準偏差は±17%だった。
評価のされ方
Max STDDEV(標準偏差の最大値) を超えない
= ばらつきの大きいテストは失敗
かつ
Baseline(基準値)より早い時間で処理が終わる
= 遅いと失敗
この2つの要素を満たしていれば成功、それ以外は失敗となります。 今回の例だとBaselineよりも20.788%高速だったが、標準偏差は±17%とMax STDDEVの10%を上回った為、失敗となります。
注意
動作スピードは実機とシミュレータで異なる為、ターゲットとする実機で検証することをお勧めします。
まとめ
- Xcode 6からユニットテストと同様にパフォーマンステストも計測して評価できるようになりました。
- Botsでも回せるようです。多分TravisやJenkinsでもいけます。多分。
- 数値化できるって楽しい!
この内容は勉強会で話した内容となっており、スライドも公開しています。併せてご覧ください。