iOS代码执行时间

在测试代码效率是往往会用到

StackOverflow How to log a method’s execution time exactly in milliseconds?

1
2
3
4
5
//单位换算
1分(min)=60秒(s)
1秒(s)=1000毫秒(ms)
1毫秒(ms)=1000微秒(μs)
1微秒(μs)=1000纳秒(ns)

一、CFAbsoluteTime (纳秒级的精确度 )

1
2
3
4
5
6
CFAbsoluteTime startTime =CFAbsoluteTimeGetCurrent();
//在这写入要计算时间的代码
...
CFAbsoluteTime executionTime = (CFAbsoluteTimeGetCurrent() - startTime);
NSLog(@"executionTime %f ms", executionTime *1000.0);
//打印出来代码执行时间 单位ms(executionTime 7.062972 ms)

block方式

c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TIME_BLOCK(^{
//执行需要测试的代码
});


CGFloat TIME_BLOCK(void (^block)(void)){
NSTimeInterval startTime = CACurrentMediaTime();
block ();
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
NSLog(@"executionTime = %f ms", elapsedTime *1000.0);
return (CGFloat)elapsedTime / NSEC_PER_SEC;
}


//key 标识符
CGFloat TIME_BLOCKWithkey (NSString *key,void (^block)(void)) {
NSTimeInterval startTime = CACurrentMediaTime();
block ();
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
NSLog(@"%@ executionTime = %f ms",key,elapsedTime *1000.0);
return (CGFloat)elapsedTime / NSEC_PER_SEC;
}

二、NSDate

c
1
2
3
4
5
6
NSDate *methodStart = [NSDate date];
/* ... Do whatever you need to do ... */
NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f ms", executionTime *1000.0);
//打印出来为代码执行时间 单位ms(7.090032 ms)

简写宏

1
2
3
4
5
6
7
宏定义
#define TICK NSDate *startTime = [NSDate date]
#define TOCK NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])

TICK
/* ... Do Some Work Here ... */
TOCK

三、CACurrentMediaTime()返回的精度-微秒级别

CACurrentMediaTime方法获取到的时间,是手机从开机一直到当前所经过的秒数。

1
2
3
4
5
6
NSTimeInterval startTime = CACurrentMediaTime();

// your code goes here
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
NSLog(@"executionTime = %f ms", elapsedTime *1000.0);
//打印出来为代码执行时间 单位ms(7.299827 ms)
  • NSDate 属于Foundation
  • CFAbsoluteTimeGetCurrent() 属于 CoreFoundatio
  • CACurrentMediaTime() 属于 QuartzCore

第二种:(将运行代码放入下面的Block中,返回时间)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import <mach/mach.h>
#import <mach/mach_time.h> // for mach_absolute_time() and friends

CGFloat TIME_BLOCK (void (^block)(void)) {
mach_timebase_info_data_t info;
if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;

uint64_t start = mach_absolute_time ();
block ();
uint64_t end = mach_absolute_time ();
uint64_t elapsed = end - start;

uint64_t nanos = elapsed * info.numer / info.denom;
return (CGFloat)nanos / NSEC_PER_SEC;
}

//加入key
CGFloat TIMEKey_BLOCK(NSString *key, void (^block)(void)) {
mach_timebase_info_data_t info;
if (mach_timebase_info(&info) != KERN_SUCCESS)
{
return -1.0;
}

uint64_t start = mach_absolute_time();
block();
uint64_t end = mach_absolute_time();
uint64_t elapsed = end - start;

uint64_t nanos = elapsed * info.numer / info.denom;
float cost = (float)nanos / NSEC_PER_SEC;

NSLog(@"key: %@ (%f ms)\n", key, cost * 1000);
return cost;
}


uint64_t getTickCount(void)
{
static mach_timebase_info_data_t sTimebaseInfo;
uint64_t machTime = mach_absolute_time();

// Convert to nanoseconds - if this is the first time we've run, get the timebase.
if (sTimebaseInfo.denom == 0 )
{
(void) mach_timebase_info(&sTimebaseInfo);
}

// Convert the mach time to milliseconds
uint64_t millis = ((machTime / 1000000) * sTimebaseInfo.numer) / sTimebaseInfo.denom;
return millis;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 计算脚本时间
* @param $last 最后一次的运行clock
* @param $key 标识
* @return 当前clock
*/
double timeNow(double last, char* key){
clock_t now = clock();
printf("time:%fs \t key:%s \n", (last != 0) ? (double)(now - last) / CLOCKS_PER_SEC : 0, key);
return now;
}

double t1 = t(0, "");
//do something
t(t1, "end");

参考:

iOS关于时间的处理

文章作者: kyren
文章链接: http://huluo666.github.io/2017/12/27/iOS代码执行时间/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Kyren's Blog