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

はじめに

Xcode 6 でユニットテストのようにパフォーマンスをテストする機能が追加されました。
これによって重そうなロジックにパフォーマンスの測定を設定しておき常に計測することができます。 例えば、画像や動画、音声など圧縮データのエンコード/デコード処理、大量のデータをソートする処理、暗号化する処理などが、ざっと思いつく重い処理です。 今回はサンプルとしてログ出力で追加されたprintlnとNSLogのパフォーマンスを比較してみます。

測定してみる

パフォーマンスの測定はユニットテストと同じように扱われますが、Assertがある訳ではなくself.measureBlock()の中で呼び出されたコードが計測対象になります。 新規にプロジェクトを作成するとTestクラスが作成されますが、そこにもself.measureBlock()が作成されるようになりました。

今回必要なソース

テストされるクラス [Swift file_name="Logger.swift"] class Logger { let max = 10000

func writeNSLog(){ for var i = 0; i < max; i++ { NSLog("%d",i) } } func writePrintln(){ for var i = 0; i < max; i++ { println(String(i)) } } } [/Swift]

テストクラス [Swift file_name="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() } } } [/Swift]

どうやって計測するのか

ユニットテストと同様にTest Navigatorや⌘+Uで実行可能です。 BotsTests_swift1-2539

実行するとテストコードに結果が表示され、テストコードのグレーになった部分をクリックすると詳細が表示されます。

何をどう計測しているのか

10回計測し平均(Average)と標準偏差(STDDEV)を求めています。

BotsTests_swift-1230

標準偏差って

どれだけデータがバラついているか、の指標

標準偏差(ひょうじゅんへんさ、英語: Standard Deviation)は、分散の正の平方根である。統計値や確率変数の散らばり具合(ばらつき)を表す数値のひとつであり、σ や s で表す。例えば、ある試験でクラス全員が同じ点数であった場合(すなわち全員が平均値であった場合)、データにはばらつきがないので、標準偏差と分散は0になる。

Wikipediaより

表示項目

01-1798

  • Result: 評価の結果
  • Average: 10回計測した時間の平均値
  • Baseline: この値を下回ればテスト失敗とみなす
  • Max STDDEV: 標準偏差の最大値。この値を上回れば失敗とみなす

評価のさせ方

最初にテストした時点ではResultとBaselineに"No Baseline"と表示されます。Set BaselineボタンをクリックすればBaselineにAverageの値が入り、基準値として設定されます。またEditボタンでBaselineとMax STDDEVは編集可能です。
その上でもう一度計測してみましょう。

すると、Resultに値が入ってきました!

評価の見方

03-1848

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でもいけます。多分。
  • 数値化できるって楽しい!

この内容は勉強会で話した内容となっており、スライドも公開しています。併せてご覧ください。