赞
踩
最近看到文章1表示Switch比If慢,这里就来测试一下是否属实。
立刻打开VS,编写以下代码:
#include<stdio.h> #include<stdlib.h> #include<time.h> #define MAX_LOOP 100000000 int nums[5]; void switchFunc() { int i, r; srand((unsigned)time(NULL)); for (i = 0; i < MAX_LOOP; i++) { r = rand() % 5; switch (r) { case 3: nums[3]++; break; case 1: nums[1]++; break; case 2: nums[2]++; break; case 0: nums[0]++; break; default: nums[4]++; break; } } } void ifFunc() { int i, r; srand((unsigned)time(NULL)); for (i = 0; i < MAX_LOOP; i++) { r = rand() % 5; if (r == 3) nums[3]++; else if (r == 1) nums[1]++; else if (r == 2) nums[2]++; else if (r == 0) nums[0]++; else nums[4]++; } } int main() { clock_t start, finish, i; double if_time, switch_time, if_total_time = 0, switch_total_time = 0; int test_time = 10; printf("Start test.\n"); printf(" \tswitch time\tif time\n"); for (i = 0; i < test_time; i++) { memset(nums, 0, sizeof(nums)); start = clock(); switchFunc(); finish = clock(); switch_time = (double)1000.0 * (finish - start) / CLOCKS_PER_SEC; switch_total_time += switch_time; start = clock(); ifFunc(); finish = clock(); if_time = (double)1000.0 * (finish - start) / CLOCKS_PER_SEC; if_total_time += if_time; printf("#%d\t%0.0fms\t\t%0.0fms\n", i + 1, switch_time, if_time); } printf("\n"); printf("total\t%0.0fms\t\t%0.0fms\n", switch_total_time / test_time, if_total_time / test_time); return 0; }
使用VS2022编译,在ReleaseX84环境下运行结果为:
Start test.
switch time if time
#1 3929ms 3673ms
#2 3590ms 3584ms
#3 3606ms 3587ms
#4 3604ms 3585ms
#5 3601ms 3589ms
#6 3589ms 3586ms
#7 3605ms 3584ms
#8 3596ms 3581ms
#9 3591ms 3592ms
#10 3605ms 3593ms
total 3632ms 3595ms
测试结果表明,switch确实比if慢。这个原因来自CPU 分支预测2。
编译器根据case的数量和case值的稀疏程度来翻译switch语句,当case情况比较多(例如4个以上),并且值的范围跨度比较小时,就会使用跳转表。
构建的跳转表为
.text:00415A6C jpt_4159A7 dd offset $LN10_0 ; DATA XREF: _switchFunc+97↑r
.text:00415A6C dd offset $LN8 ; jump table for switch statement
.text:00415A6C dd offset $LN9_0
.text:00415A6C dd offset $LN7
增加了条件到0-9以后,swtich比if快。
修改后的代码如下:
#include<stdio.h> #include<stdlib.h> #include<time.h> #define MAX_LOOP 100000000 int nums[10]; void switchFunc() { int i, r; srand((unsigned)time(NULL)); for (i = 0; i < MAX_LOOP; i++) { r = rand() % 10; switch (r) { case 8: nums[8]++; break; case 3: nums[3]++; break; case 7: nums[7]++; break; case 1: nums[1]++; break; case 4: nums[4]++; break; case 2: nums[2]++; break; case 0: nums[0]++; break; case 6: nums[6]++; break; case 5: nums[5]++; break; default: nums[9]++; break; } } } void ifFunc() { int i, r; srand((unsigned)time(NULL)); for (i = 0; i < MAX_LOOP; i++) { r = rand() % 10; if (r == 8) nums[8]++; else if (r == 3) nums[3]++; else if (r == 7) nums[7]++; else if (r == 1) nums[1]++; else if (r == 4) nums[4]++; else if (r == 2) nums[2]++; else if (r == 0) nums[0]++; else if (r == 6) nums[6]++; else if (r == 5) nums[5]++; else nums[9]++; } } int main() { clock_t start, finish, i; double if_time, switch_time, if_total_time = 0, switch_total_time = 0; int test_time = 10; printf("Start test.\n"); printf(" \tswitch time\tif time\n"); for (i = 0; i < test_time; i++) { memset(nums, 0, sizeof(nums)); start = clock(); switchFunc(); finish = clock(); switch_time = (double)1000.0 * (finish - start) / CLOCKS_PER_SEC; switch_total_time += switch_time; start = clock(); ifFunc(); finish = clock(); if_time = (double)1000.0 * (finish - start) / CLOCKS_PER_SEC; if_total_time += if_time; printf("#%d\t%0.0fms\t\t%0.0fms\n", i + 1, switch_time, if_time); } printf("\n"); printf("total\t%0.0fms\t\t%0.0fms\n", switch_total_time / test_time, if_total_time / test_time); return 0; }
结果如下:
Start test.
switch time if time
#1 3962ms 3900ms
#2 3732ms 3787ms
#3 3750ms 3794ms
#4 3738ms 3794ms
#5 3727ms 3796ms
#6 3735ms 3785ms
#7 3729ms 3797ms
#8 3725ms 3799ms
#9 3744ms 3800ms
#10 3739ms 3784ms
total 3758ms 3804ms
当条件分支比较少的情况下,if比较快,当条件分支比较多的情况下,swtich比较快。
为什么新一代的Rust、Go等编程语言都如此讨厌if-else、Switch结构 https://mp.weixin.qq.com/s?__biz=MjM5MjAwODM4MA==&mid=2650863132&idx=2&sn=8372881079ff08caaaab6402b701b472&chksm=bd5887cf8a2f0ed992ad407e346d14b1241f99d8e3247013be926821031d4ba0a4d9049955da&mpshare=1&scene=23&srcid=0817mTwF5NsGURzy0x2dGxQQ&sharer_sharetime=1629187233862&sharer_shareid=d3275e0a17ca4e2cadeabadfeb76ff9f#rd ↩︎
为什么很多程序员不用switch,而是大量的if else?|字节|代码|跳转|预测器_网易订阅 https://www.163.com/dy/article/G6H4B7RT05319WXB.html ↩︎
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。