C/C++打假:条件分支语句switch..case效率比if..else高?

         很久很久以前,有人教导我说条件分支大于4条时,switch..case效率会比if..else高,条件分支为10条时,switch..case效率会比if..else快一倍不止。随着条件分支越多,效率差异越大。今日得闲,我做了个测试来验证这条经验的真假。以下分3个case对比这两种条件选择分支的性能,每个case重复两遍以上确保测试数据稳定。测试所用系统为Ubuntu 22.04.3,编译器为gcc(version 11.4.0)和clang(version 14.0.0)

case 1:13条条件分支

#include <iostream>
#include <chrono>
#include <random>
#include <vector>using namespace std;int GetRandomNum() {// 基于时间的种子,使得每次运行程序时都能产生不同的随机数序列unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::mt19937 generator(seed); // 使用Mersenne Twister作为随机数生成器// 定义一个均匀分布的整数分布std::uniform_int_distribution<int> distribution(0, 12); // 生成0到12之间的随机数// 生成并打印一个随机数int random_number = distribution(generator);// std::cout << "随机数: " << random_number << std::endl;return random_number;
}void CheckIf(int num) {if (num == 0) {;} else if (num == 1 ) {;} else if (num == 2 ) {;} else if (num == 3 ) {;        } else if (num == 4 ) {;        } else if (num == 5 ) {;        } else if (num == 6 ) {;        } else if (num == 7 ) {;        } else if (num == 8 ) {;        } else if (num == 9 ) {;        } else if (num == 10 ) {;        } else if (num == 11 ) {;        } else {;        }
}void CheckSwitch(int num) {switch (num) {case 0: {break;}case 1: {break;}case 2: {break;}case 3: {break;}case 4: {break;}case 5: {break;}case 6: {break;}case 7: {break;}case 8: {break;}case 9: {break;}case 10: {break;}case 11: {break;}default: {break;}}
}int main() {int loop_count = 10000000;int index = 0;vector<int> nums;std::cout << "Start test. loop_count:" << loop_count << std::endl;// 生成1000万个随机数比较耗时,在我电脑上大概要50秒while (index < loop_count) {nums.push_back(GetRandomNum());++index;}std::cout << "nums is ready." << std::endl;index = 0;// 获取开始时间点auto start = std::chrono::high_resolution_clock::now();while (index < loop_count) {CheckSwitch(nums[index]);++index;}// 获取结束时间点auto end = std::chrono::high_resolution_clock::now();// 计算时间差auto duration_switch = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);index = 0;// 获取开始时间点start = std::chrono::high_resolution_clock::now();while (index < loop_count) {CheckIf(nums[index]);++index;}// 获取结束时间点end = std::chrono::high_resolution_clock::now();// 计算时间差auto duration_if = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);// 输出结果std::cout << "执行switch时间: " << duration_switch.count() << " 毫秒" << std::endl;std::cout << "执行if时间: " << duration_if.count() << " 毫秒" << std::endl;return 0;
}

   gcc编译运行输出如下,if耗时是switch的53%

执行switch时间: 26 毫秒
执行if时间: 14 毫秒

   clang编译运行输出如下,switch耗时是if的72%

执行switch时间: 127 毫秒
执行if时间: 176 毫秒

case 2:5条条件分支

void CheckIf(int num) {if (num == 0) {;} else if (num == 1 ) {;} else if (num == 2 ) {;} else if (num == 3 ) {;        // } else if (num == 4 ) {//     ;        // } else if (num == 5 ) {//     ;        // } else if (num == 6 ) {//     ;        // } else if (num == 7 ) {//     ;        // } else if (num == 8 ) {//     ;        // } else if (num == 9 ) {//     ;        // } else if (num == 10 ) {//     ;        // } else if (num == 11 ) {//     ;        } else {;        }
}void CheckSwitch(int num) {switch (num) {case 0: {break;}case 1: {break;}case 2: {break;}case 3: {break;}// case 4: {//     break;// }// case 5: {//     break;// }// case 6: {//     break;// }// case 7: {//     break;// }// case 8: {//     break;// }// case 9: {//     break;// }// case 10: {//     break;// }// case 11: {//     break;// }default: {break;}}
}

   gcc编译运行输出如下,if耗时是switch的30%

执行switch时间: 50 毫秒
执行if时间: 15 毫秒

 clang编译运行输出如下,switch耗时是if的93%

执行switch时间: 55 毫秒
执行if时间: 59 毫秒

case 3:3条条件分支

void CheckIf(int num) {if (num == 0) {;} else if (num == 1 ) {;// } else if (num == 2 ) {//     ;// } else if (num == 3 ) {//     ;        // } else if (num == 4 ) {//     ;        // } else if (num == 5 ) {//     ;        // } else if (num == 6 ) {//     ;        // } else if (num == 7 ) {//     ;        // } else if (num == 8 ) {//     ;        // } else if (num == 9 ) {//     ;        // } else if (num == 10 ) {//     ;        // } else if (num == 11 ) {//     ;        } else {;        }
}void CheckSwitch(int num) {switch (num) {case 0: {break;}case 1: {break;}// case 2: {//     break;// }// case 3: {//     break;// }// case 4: {//     break;// }// case 5: {//     break;// }// case 6: {//     break;// }// case 7: {//     break;// }// case 8: {//     break;// }// case 9: {//     break;// }// case 10: {//     break;// }// case 11: {//     break;// }default: {break;}}
}

   gcc编译运行输出如下,if耗时是switch的53%

执行switch时间: 28 毫秒
执行if时间: 15 毫秒

 clang编译运行输出如下,switch耗时是if的96%

执行switch时间: 30 毫秒
执行if时间: 31 毫秒

根据上面3个case的测试结果,可得出如下结论:

1. 在gcc上if语句执行效率不受分支条件多少的影响

2. 在gcc上if语句执行效率明显好于switch语句

3. gcc的分支语句执行效率明显好于clang

4. clang上if语句执行效率差于switch语句,且随着条件分支越多,效率差异越大

5. 分支语句执行很快,只包含分支语句的函数调用耗时为10的负9次方秒。

总结:因为分支语句执行很快,大多数情况下我们跟随自己的内心,自由选择即可。如果你用的gcc,且需考虑条件语句执行效率的话闭眼选if语句。如果你用的clang,且需考虑条件语句执行效率时,条件分支条数小于6时可自由选择,条件分支条数大于6时,选switch语句;万一的情况下,条件分支语句执行效率成为了软件性能的一个较大阻塞点,可以考虑舍弃clang选gcc。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/32010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pyqt5 信号和槽函数以及Qthread 多线程的简单的例子

写了一个简单的例子&#xff1a; 包含一个主窗口和一个按钮。点击按钮时&#xff0c;我们将启动一个耗时的任务&#xff08;在这里我们使用time.sleep来模拟&#xff09;。为了不阻塞主线程&#xff0c;我们将在一个单独的线程中运行这个任务。同时&#xff0c;我们将显示一个进…

论文解读:Autoregressive Image Generation without Vector Quantization

这篇论文的主要内容围绕着一个核心问题&#xff1a;是否有必要将自回归模型与向量量化的表示方式绑定在一起&#xff0c;特别是在图像生成领域&#xff1f;作者团队来自麻省理工学院计算机科学与人工智能实验室&#xff08;MIT CSAIL&#xff09;、谷歌DeepMind以及清华大学&am…

力扣SQL 即时食物配送 II min函数 嵌套查询

Problem: 1174. 即时食物配送 II &#x1f468;‍&#x1f3eb; 参考题解 Code -- 计算立即配送的订单百分比 select round (-- 计算订单日期与客户偏好配送日期相同的订单数量sum(case when order_date customer_pref_delivery_date then 1 else 0 end) * 100 /-- 计算总订…

基于深度学习的图像识别技术与应用是如何?

基于深度学习的图像识别技术与应用在当今社会中扮演着越来越重要的角色。以下是对该技术与应用的详细解析&#xff1a; 一、技术原理 深度学习是一种模拟人脑处理和解析数据的方式的技术和方法论。在图像识别领域&#xff0c;深度学习主要通过深度神经网络&#xff08;如卷积…

CentOS7在2024.6.30停止维护后,可替代的Linux操作系统

背景 Linux的发行版本可以大体分为两类&#xff0c;一类是商业公司维护的发行版本&#xff0c;一类是社区组织维护的发行版本&#xff0c;前者以著名的Redhat&#xff08;RHEL&#xff09;为代表&#xff0c;后者以Debian为代表。国内占有率最多的却是Centos&#xff0c;这是由…

最全信息收集工具集

吉祥学安全知识星球&#x1f517;除了包含技术干货&#xff1a;Java代码审计、web安全、应急响应等&#xff0c;还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 所有的攻防、渗透第一步肯定是信息收集了&#xf…

CID引流电商助力3C产品销售腾飞的实践与思考

摘要&#xff1a;随着互联网技术的不断发展和普及&#xff0c;电商行业迎来了前所未有的发展机遇。其中&#xff0c;CID引流电商作为一种新兴的电商模式&#xff0c;为商家们提供了更加精准、高效的拓客之路。尤其在3C产品领域&#xff0c;CID引流电商更是助力其销售腾飞的重要…

Python 学习 第四册 第10章 系统(2)

-----用教授的方式学习 目录 10.3 进程 10.3.1 使用subprocess创建进程 10.3.2 使用multiprocessing创建进程 10.3.3 使用terminate()终止进程 10.4 日期和时间 10.4.1 datetime模块 10.4.2 使用time模块 10.4.3 读写日期和时间 10.3 进程 当运行一个程序时,操…

云计算【第一阶段(18)】磁盘管理与文件系统

一、磁盘基础 磁盘&#xff08;disk&#xff09;是指利用磁记录技术存储数据的存储器。 磁盘是计算机主要的存储介质&#xff0c;可以存储大量的二进制数据&#xff0c;并且断电后也能保持数据不丢失。 早期计算机使用的磁盘是软磁盘&#xff08;Floppy Disk&#xff0c;简称…

程序猿大战Python——面向对象——魔法方法

什么是魔法方法&#xff1f; 目标&#xff1a;了解什么是魔法方法&#xff1f; 魔法方法指的是&#xff1a;可以给Python类增加魔力的特殊方法。有两个特点&#xff1a; &#xff08;1&#xff09;总是被双下划线所包围&#xff1b; &#xff08;2&#xff09;在特殊时刻会被…

调查问卷管理系统设计文档

一、项目背景和目标 随着现代企业对市场研究的深入&#xff0c;调查问卷已成为获取用户反馈和市场动态的重要工具。为了高效管理问卷的创建、发布、回收和分析&#xff0c;我们设计了一套调查问卷管理系统。本系统的目标是提供一个功能完善、操作简便、性能稳定的平台&#xff…

MURF3040CTR-ASEMI智能AI应用MURF3040CTR

编辑&#xff1a;ll MURF3040CTR-ASEMI智能AI应用MURF3040CTR 型号&#xff1a;MURF3040CTR 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 恢复时间&#xff1a;35ns 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;30A 最大循环峰值反向电压&#xff08;VR…

CSS详解

盒子模型&#xff08;box-sizing&#xff09; line-height与height CSS选择符和可继承属性 属性选择符&#xff1a; 示例&#xff1a;a[target"_blank"] { text-decoration: none; }&#xff08;选择所有target"_blank"的<a>元素&#xff09; /* 选…

嵌入式Linux驱动开研发流程详细解析

大家好,今天主要给大家分享一下,嵌入式linux中重要的内容详解。 一、驱动概念 驱动与底层硬件直接打交道,充当了硬件与应用软件中间的桥梁。 具体任务 读写设备寄存器(实现控制的方式) 完成设备的轮询、中断处理、DMA通信(CPU与外设通信的方式) 进行物理内存向虚拟内存…

Linux中find命令总结

Linux中find命令总结 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. find命令概述 在Linux系统中&#xff0c;find命令是一种用于在文件系统中搜索文件和目…

[已解决]ImportError: DLL load failed while importing win32api: 找不到指定的程序。

使用pip install pywin32302安装后import找不到win32api 失败尝试 上网找别人的解决方案&#xff0c;大部分解决方案都是通过复制下面两个dll文件到 下面这个文件夹&#xff0c;并且复制到C:\Windows\System32&#xff0c;从而解决问题&#xff0c;但是我没能成功。 解决方…

深度神经网络——什么是小样本学习?

引言 小样本学习是指使用极少量的训练数据来开发人工智能模型的各种算法和技术。小样本学习致力于让人工智能模型在接触相对较少的训练实例后识别和分类新数据。小样本训练与训练机器学习模型的传统方法形成鲜明对比&#xff0c;传统方法通常使用大量训练数据。小样本学习是 主…

【IC验证】UVM实验lab03

1. TLM端口的创建、例化与使用 创建&#xff1a; uvm_get_blocking_port #(fmt_trans) mon_bp_port; 例化&#xff1a; function new(string name "mcdf_refmod", uvm_component parent);super.new(name, parent);fmt_trans new("fmt_trans", this);…

解析Java中1000个常用类:Base64类,你学会了吗?

推荐一个我自己写的程序员在线工具站: http://cxytools.com 提供一站式在线工具平台,专为程序员设计,包括时间日期、JSON处理、SQL格式化、随机字符串生成、UUID生成、随机数生成、文本Hash等功能,提升开发效率。 以下是正文。 在现代软件开发中,数据的编码与解码是常见…

纤程与协程以及有栈协程和无栈协程的区别

纤程与协程区别以及有栈协程和无栈协程的区别 参考纤程与协程区别有栈协程和无栈协程有栈协程为什么需要申请内存而无栈为什么不需要 参考 当谈论协程时&#xff0c;我们在谈论什么 从无栈协程到 C异步框架&#xff08;上&#xff09; 从无栈协程到 C异步框架&#xff08;下&a…