- 從上一篇文章alloc init new方法的探索中提到
slowpath
與fastpath
這兩個(gè)宏,其與編譯器優(yōu)化相關(guān)阳谍,下面來(lái)詳細(xì)闡述一下實(shí)現(xiàn)的基本原理;
slowpath
與fastpath
的宏定義如下:
#define fastpath(x) (__builtin_expect(bool(x), 1))
#define slowpath(x) (__builtin_expect(bool(x), 0))
- 為了理解上面的兩個(gè)宏汤踏,首先我們來(lái)舉個(gè)例子:看下面的代碼:
if (x) {
return 1;
}else{
return 0;
}
由于計(jì)算機(jī)并不是一次只讀取一條指令推正,而是一次會(huì)讀取多條指令觅赊,所以在讀到 if 語(yǔ)句時(shí)也會(huì)把 return 1 讀取進(jìn)來(lái)龙助,如果 x 為 0蔗坯,那么會(huì)重新讀取 return 0康震,重讀指令相對(duì)來(lái)說(shuō)比較耗時(shí);
如過(guò) x 有非常大的概率是 0宾濒,那么 return 1 這條指令每次不可避免的都會(huì)被讀取腿短,但實(shí)際上幾乎沒(méi)有機(jī)會(huì)執(zhí)行,造成了不必要的指令重讀,當(dāng)然答姥,最簡(jiǎn)單的優(yōu)化就是:
if (!x) {
return 0;
}else{
return 1;
}
- 然而對(duì)程序員來(lái)說(shuō),每次都做這樣的判斷非常燒腦谚咬,而且容易出錯(cuò)鹦付,于是 GCC 提供了一個(gè)內(nèi)置函數(shù) __builtin_expect:
long __builtin_expect (long EXP, long C)
它的返回值就是整個(gè)函數(shù)的返回值,參數(shù) C 代表預(yù)計(jì)的值择卦,表示程序員知道 EXP 的值很可能就是 C敲长,大概率就是C;
-
回到上面的兩個(gè)宏:
- fastpath(x) (__builtin_expect(bool(x), 1)) 表明x為真的概率更大秉继;
- slowpath(x) (__builtin_expect(bool(x), 0)) 表明x為假的概率更大祈噪;
//x = !cls->ISA()->hasCustomAWZ() 為真的概率更大 執(zhí)行if中的語(yǔ)句
if (fastpath(!cls->ISA()->hasCustomAWZ())) {
return _objc_rootAllocWithZone(cls, nil);
}
//x = checkNil && !cls 為假的概率更大 執(zhí)行else中的語(yǔ)句
if (slowpath(checkNil && !cls)) return nil;