- 从上一篇文章alloc init new方法的探索中提到
slowpath
与fastpath
这两个宏,其与编译器优化相关,下面来详细阐述一下实现的基本原理;
slowpath
与fastpath
的宏定义如下:
#define fastpath(x) (__builtin_expect(bool(x), 1))
#define slowpath(x) (__builtin_expect(bool(x), 0))
- 为了理解上面的两个宏,首先我们来举个例子:看下面的代码:
if (x) {
return 1;
}else{
return 0;
}
-
由于计算机并不是一次只读取一条指令,而是一次会读取多条指令,所以在读到 if 语句时也会把 return 1 读取进来,如果 x 为 0,那么会重新读取 return 0,重读指令相对来说比较耗时;
-
如过 x 有非常大的概率是 0,那么 return 1 这条指令每次不可避免的都会被读取,但实际上几乎没有机会执行,造成了不必要的指令重读,当然,最简单的优化就是:
if (!x) {
return 0;
}else{
return 1;
}
- 然而对程序员来说,每次都做这样的判断非常烧脑,而且容易出错,于是 GCC 提供了一个内置函数 __builtin_expect:
long __builtin_expect (long EXP, long C)
-
它的返回值就是整个函数的返回值,参数 C 代表预计的值,表示程序员知道 EXP 的值很可能就是 C,大概率就是C;
-
回到上面的两个宏:
- fastpath(x) (__builtin_expect(bool(x), 1)) 表明x为真的概率更大;
- slowpath(x) (__builtin_expect(bool(x), 0)) 表明x为假的概率更大;
//x = !cls->ISA()->hasCustomAWZ() 为真的概率更大 执行if中的语句
if (fastpath(!cls->ISA()->hasCustomAWZ())) {
return _objc_rootAllocWithZone(cls, nil);
}
//x = checkNil && !cls 为假的概率更大 执行else中的语句
if (slowpath(checkNil && !cls)) return nil;
网友评论