時間計測には NSDateを使用する方法 と gettimeofday()を使用する方法があります。
最近のCPUは、早いからどちらでもあまり問題なならないのですが、
前々から、どちらが早いのか知りたくてテストしました。
結果からするとほぼ同じでNSDateが気持ち遅いかな程度なのですが、予想外な事がわかりました。
環境はXcode7.0で ターゲットはiPhone5s(ios8.3)です。
まず、Codeから
Global変数
struct timeval start_time;
struct timeval current_time;
NSDate *measureTime;
NSDate *totalTime;処理
double sum; totalTime = [NSDate date]; for( int loop=0;loop<10;loop++) { sum=0.0;
NSDateの場合
for( int i=0;i<100;i++) { measureTime = [NSDate date]; [NSThread sleepForTimeInterval:0.1]; NSTimeInterval dt = -[measureTime timeIntervalSinceNow]; sum+=dt; }
gettimeofdayの場合
for( int i=0;i<100;i++) { gettimeofday(&start_time, NULL); [NSThread sleepForTimeInterval:0.1]; gettimeofday(¤t_time, NULL); double start = (double)start_time.tv_sec+(double)start_time.tv_usec/1000000.0; double current = (double)current_time.tv_sec+(double)current_time.tv_usec/1000000.0; double dt = current-start; sum+=dt; }
NSLog(@"time=%f",sum/100.0); } NSLog(@"totalTime=%f",-[totalTime timeIntervalSinceNow]);
内容
・0.1秒寝ている時間を100回測定して平均時間を測定する。
・それを10回実行して全体時間を測定する。
・結果はLogで出力
結果からgettimeofday()が早いとなるのだが、・・・・・・・
んんんん 100msのSleepで平均101msなのが気に入らない
100msのSleepは本当に100msか確認
( [NSThread sleepForTimeInterval:0.1];のみで全体時間測定 )
1ms余分にかかってましたね。ならば、実質の測定全体時間は、
NSDate : 101.090191-101.075412 = 0.014779 秒(100回x10回)
gettimeofday: 101.078647-101.075412 = 0.003235 秒(100回x10回)
となるのですが、
1回あたり 14us と 3us・・・・・
んんんん 桁違うじゃん 4倍も違う なんで 誤差????
SleepなければNSDateとgettimeofdayの測定時間がどうなるか確認
( [NSThread sleepForTimeInterval:0.1];を削除で全体時間測定 )
まずは、NSDate
次にgettimeofday
さっきの計算でgettimeofdayは、1回あたり3usだったから
そんなに差がないじゃん??????
単体計算では
NSDateの場合
101.075412(Sleep全体時間) + 0.002940(測定全体時間) = 101.078352 秒(100回x10回)
gettimeofdayの場合
101.075412(Sleep全体時間) + 0.002428(測定全体時間) = 101.07784 秒(100回x10回)
なので、ほとんど差がないはずなのですが、
実際(最初の測定)の結果と比較すると
NSDateの場合 101.090191 秒 -> 101.078352 秒 (差0.011839秒)
gettimeofdayの場合 101.075412 秒 -> 101.07784 秒 (差-0.002428秒)
これは、推測ですが、NSDateの場合は、Sleep処理になんらかの負荷をかけている
または、Sleep処理組み合わさった場合にコードの最適化がよくない等と思います。
(まあ問題にするほどの事ではないですがね・・・・・)
テスト結果
・ほとんど同じですが、NSDateが気持ち遅いかな程度。
・Sleepと組み合わせると追加の気持ち時間が追加される。