当前位置:   article > 正文

c语言的If与Switch效率比较_c if 和switch那个效率高

c if 和switch那个效率高

最近看到文章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;
}
  • 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
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

使用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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

测试结果表明,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
  • 1
  • 2
  • 3
  • 4

增加了条件到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;
}
  • 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
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

结果如下:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结论

当条件分支比较少的情况下,if比较快,当条件分支比较多的情况下,swtich比较快。


  1. 为什么新一代的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 ↩︎

  2. 为什么很多程序员不用switch,而是大量的if else?|字节|代码|跳转|预测器_网易订阅 https://www.163.com/dy/article/G6H4B7RT05319WXB.html ↩︎

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/142164?site
推荐阅读
相关标签
  

闽ICP备14008679号