看linux源码或者一些优秀组件的源码,经常碰到likely和unlikely, 其实很简单,无非就是显式告诉编译器怎么去优化。有兴趣的话,可以看看对应的汇编。下面,我们来实际测试一下likely/unlikely的性能优化效果:
- #include <stdio.h>
- #include<sys/time.h>
- #define likely(x) __builtin_expect(!!(x), 1)
- #define unlikely(x) __builtin_expect(!!(x), 0)
- #define N (1000 * 1000 * 1000)
-
- int64_t printTime(int64_t iT1)
- {
- struct timeval t2;
- gettimeofday(&t2, NULL);
- int64_t iT2 = t2.tv_sec * 1000000 + t2.tv_usec;
- int64_t gap = iT2 - iT1;
- printf("gap is %lld\n", gap);
- return t2.tv_sec * 1000000 + t2.tv_usec;
- }
-
- int fun1()
- {
- int a = 0;
- for (int i = 0; i < N; i++)
- {
- if (i < 0)
- {
- a--;
- }
- else
- {
- a++;
- }
- }
-
- return a;
- }
-
- int fun2()
- {
- int a = 0;
- for (int i = 0; i < N; i++)
- {
- if (i >= 0)
- {
- a++;
- }
- else
- {
- a--;
- }
- }
-
- return a;
- }
-
- int fun3() // 逻辑等价于fun1
- {
- int a = 0;
- for (int i = 0; i < N; i++)
- {
- if (unlikely(i) < 0)
- {
- a--;
- }
- else
- {
- a++;
- }
- }
-
- return a;
- }
-
- int fun4() // 逻辑等价于fun2
- {
- int a = 0;
- for (int i = 0; i < N; i++)
- {
- if (likely(i) >= 0)
- {
- a++;
- }
- else
- {
- a--;
- }
- }
-
- return a;
- }
-
- int main()
- {
- struct timeval t;
- int64_t iT = 0;
- gettimeofday(&t, NULL);
-
- fun1();
- iT = printTime(t.tv_sec * 1000000 + t.tv_usec);
-
- fun2();
- iT = printTime(iT);
-
- fun3();
- iT = printTime(iT);
-
- fun4();
- iT = printTime(iT);
- return 0;
- }
运行三次,结果:
taoge:~$ ./a.out
gap is 2777564
gap is 2432064
gap is 1788922
gap is 1872011
taoge:~$ ./a.out
gap is 2792285
gap is 2384819
gap is 1787595
gap is 1829156
taoge:~$ ./a.out
gap is 2798899
gap is 2423693
gap is 1786800
gap is 1830484
不多说。