2011年 4月 06日(水曜日) 00:07

iOSアプリでのパフォーマンス測定方法

評価:
(0 票)

iOSアプリの開発では、PCに比べてメモリやCPUの処理速度に限界があるので、パフォーマンスがとても気になります。

そこで、パフォーマンスの測定方法を考えてみました。

馴染みのあるCocoa Touchのクラスを使うなら、[[NSDate date] timeIntervalSince1970]などを使えば時間を取得できますが、秒単位でしか取得できず、処理時間を計るのには使えません。

NSLogを使えば、

2011-04-06 00:15:04.185

のように、ミリ秒単位の時刻が表示されますが、NSLog自体が非常に遅いので、これも細かい処理時間を計るのには向いていません。

調べてみると、より精細な時間を計るには、gettimeofdayシステムコールを使うのが良さそうです。これはマイクロ秒単位で計ることができる上、システム関数なのでこの関数自体の実行速度も高速なはずです。

使い方は、

man 2 gettimeofday

で見られますが、Java育ちの自分にはシステムコールとかあまり馴染みがないので、詳細を書いておきます。

まず、ヘッダファイルで<sys/time.h>をインクルードする必要があります。

#import <sys/time.h>

コードでは測定したい箇所の前後に次のように書きます。

struct timeval ts;
gettimeofday(&ts, NULL);

// ここに測定したい処理の内容を記述

struct timeval te;
gettimeofday(&te, NULL);
double startTime = ts.tv_sec + ts.tv_usec * 1e-6;
double endTime = te.tv_sec + te.tv_usec * 1e-6;
NSLog(@"Finished in %f sec.",  endTime - startTime);

timeval構造体には、秒単位とマイクロ秒単位の値をそれぞれ整数(time_tとsuseconds_t, 実体はlongとint)で保持できて、gettimeofday関数は2番目の引数をNULLにすると一番目の引数で渡したtimeval構造体に現在時刻(1970年1月1日からの秒数)を入れてくれます。(逆に1番目をNULLにすると2番目にタイムゾーンを入れてくれる。こういう仕様がJava世代の自分にはなんか馴染めない。>_<)

毎回これを書くのは面倒なので、私は以前書いたDLogの方法にならって、共通のヘッダファイルに次のように定義して、測定したい部分をTIC()とTOC(s)で挟む感じで使っています。

#ifdef DEBUG_MODE
#define TIC() struct timeval ts; gettimeofday(&ts, NULL)
#define TOC(s) struct timeval te; gettimeofday(&te, NULL); NSLog(@"%@: %f sec", s, te.tv_sec + te.tv_usec * 1e-6 - (ts.tv_sec + ts.tv_usec * 1e-6))
#else
#define TIC()
#define TOC(s)
#endif

(ただ、これだと1つの関数のスコープ内で一度しか使えないのでご注意。1つのスコープ内でたくさん計測したいときはもうちょっと工夫が必要。)

最終更新日: 2011年 6月 27日(月曜日) 01:09
くらち たかよし

くらち たかよし

モバイル・Webアプリ作家。最近は主にiPhoneアプリ制作を手がける。企画から、UIデザイン、設計、実装、テスト、多言語対応、ユーザーサポートまでを1人〜数人の個人で行う全人的開発手法の確立を目指している。

使う言語はObjective-C, C++, C#, Java, PHPなど。Web関連で使うものはCakePHP, MySQL, Joomla! CMSなど。デザインはシロウトながらPhotoshopとIllustratorをなんとかがんばって使う。

場所や時間に縛られない、インターネット時代の新しい働き方、自由な生き方を模索中。海外移住、低予算&低リスク起業、キャリアデザイン、心理学などにも興味あり。

Web: awaresoft.jp/