C++中if-else,switch-case有什么区别,执行效率哪个更高?是否其他语句有比两者更高的执行效率?

embedded/2024/10/21 11:50:46/

在编程中,选择使用 switch-case 还是 if-else 语句通常取决于代码的可读性、维护性和特定的使用场景。对于它们的性能,以下是对它们的效率比较:

1. 基本原理

  • if-else 语句

    • if-else 是一个链式结构,条件会一个一个被评估,直到找到第一个为真的条件为止。
    • 每个条件的计算都是线性的,最坏情况下,需要检查所有的条件。
  • switch-case 语句

    • switch-case 是一个多路分支结构,通常用于处理多个可能的值(通常是整数或枚举)。
    • 它会根据给定的表达式直接跳转到相应的分支,不必像 if-else 那样逐一检查条件。
    • 在大多数情况下,编译器可以将 switch-case 优化为跳转表或哈希表,使得分支选择几乎是常数时间复杂度。

2. 性能分析

  • 编译器优化

    • switch-case

      • 当分支数目较少时,编译器通常将其实现为一系列的条件检查(类似于 if-else)。
      • 当分支数目较多并且值是连续的(或几乎连续的),编译器可能会生成一个跳转表或哈希表,从而使得分支选择是常数时间复杂度 O(1)
      • 这种优化在处理大量可能的值时非常有效。
    • if-else

      • if-else 语句在编译器上通常被编译为一系列的条件跳转指令。
      • 如果条件是简单的布尔表达式,性能差别不大。
      • 如果条件是复杂的表达式或者包含多个条件,性能会受到评估顺序和表达式复杂性的影响。
  • 具体情境下的性能

    • 小范围分支
      • 当分支数目较少时(例如,2-3 个分支),if-elseswitch-case 的性能差别通常可以忽略不计。
      • 编译器在这种情况下可能会对两者做类似的优化。
    • 大范围分支
      • 对于多于几种可能性的分支,switch-case 通常会更高效,尤其是在可以优化为跳转表的情况下。
      • 在处理大型枚举或整数范围时,switch-case 通常会有显著的性能优势。

3. 代码可读性和维护性

  • if-else

    • if-else 适合于处理多种不同类型的条件(不仅限于整数值)。
    • 更灵活,可以处理任意复杂的逻辑。
    • 可读性和代码结构在面对简单的条件时可能更清晰。
  • switch-case

    • switch-case 在处理多个固定值时更直观。
    • 对于处理固定值集的逻辑(例如状态机、命令模式),switch-case 更具可读性和结构性。

4. 总结

  • 性能

    • 在处理少量分支时,两者差异不大。
    • 在处理大量固定值的分支时,switch-case 通常更高效。
  • 代码结构

    • if-else 适合处理复杂的条件和逻辑。
    • switch-case 适合处理大量固定值的情况,并且代码更简洁、可读。

 5.执行效率

如果if判断有很多条语句判断,如何提高执行效率。如下例子,提高执行效率可以这样改写。

std::string DataLoadULog::reNamePlot(std::string name)
{
if(name=="vehicle_attitude_setpoint/pitch_body")
{
std::string plotname="6.姿态角度/俯仰角_期望";
return plotname;
}
if(name=="vehicle_attitude_setpoint/roll_body")
{
std::string plotname="6.姿态角度/滚转角_期望";
return plotname;
}
if(name=="vehicle_attitude_setpoint/yaw_body")
{
std::string plotname="6.姿态角度/偏航角_期望";
return plotname;
}
//7.姿态角速度
if(name=="vehicle_rates_setpoint/pitch")
{
std::string plotname="7.姿态角速度/俯仰角速度_期望";
return plotname;
}
if(name=="vehicle_rates_setpoint/roll")
{
std::string plotname="7.姿态角速度/滚转角速度_期望";
return plotname;
}
if(name=="vehicle_rates_setpoint/yaw")
{
std::string plotname="7.姿态角速度/偏航角速度_期望";
return plotname;
}
//4.高度信息
if(name=="sensor_gps/alt")
{
std::string plotname="4.高度信息/海拔高度(GNSS高度)";
return plotname;
}
if(name=="trajectory_setpoint/z")
{
std::string plotname="4.高度信息/融合高度_期望";
return plotname;
}
if(name=="vehicle_local_position/z")
{
std::string plotname="4.高度信息/融合高度_测量";
return plotname;
}
if(name=="vehicle_air_data/baro_alt_meter")
{
std::string plotname="4.高度信息/气压高度";
return plotname;
}
if(name=="distance_sensor/current_distance")
{
std::string plotname="4.高度信息/雷达高度";
return plotname;
}}

DataLoadULog::reNamePlot 函数中,使用了一系列的 if-else 语句来匹配输入的 name 字符串并返回对应的字符串。这种方法在分支数目较多的情况下,可能会影响性能。要提高效率,我们可以考虑以下优化方法:

使用 std::unordered_map

使用 std::unordered_map 来存储键值对,这样可以利用哈希表来实现常数时间复杂度的查找。std::unordered_map 是 C++ 标准库提供的哈希表实现,非常适合这种键值匹配的场景。

以下是如何使用 std::unordered_map 重写 reNamePlot 函数:

#include <unordered_map>
#include <string>class DataLoadULog {
public:std::string reNamePlot(const std::string& name);private:static const std::unordered_map<std::string, std::string> plotNameMap;
};// 定义并初始化 map
const std::unordered_map<std::string, std::string> DataLoadULog::plotNameMap = {{"vehicle_attitude_setpoint/pitch_body", "6.姿态角度/俯仰角_期望"},{"vehicle_attitude_setpoint/roll_body", "6.姿态角度/滚转角_期望"},{"vehicle_attitude_setpoint/yaw_body", "6.姿态角度/偏航角_期望"},{"vehicle_rates_setpoint/pitch", "7.姿态角速度/俯仰角速度_期望"},{"vehicle_rates_setpoint/roll", "7.姿态角速度/滚转角速度_期望"},{"vehicle_rates_setpoint/yaw", "7.姿态角速度/偏航角速度_期望"},{"sensor_gps/alt", "4.高度信息/海拔高度(GNSS高度)"},{"trajectory_setpoint/z", "4.高度信息/融合高度_期望"},{"vehicle_local_position/z", "4.高度信息/融合高度_测量"},{"vehicle_air_data/baro_alt_meter", "4.高度信息/气压高度"},{"distance_sensor/current_distance", "4.高度信息/雷达高度"}
};// 函数实现
std::string DataLoadULog::reNamePlot(const std::string& name) {auto it = plotNameMap.find(name);if (it != plotNameMap.end()) {return it->second;}return ""; // 或者返回一个默认值
}

优点:

  • 效率高:查找时间复杂度为 O(1)。
  • 代码简洁:清晰地将输入与输出的映射分开,容易添加新的映射。
  • 易于维护:如果需要增加或修改映射,只需在 unordered_map 中添加或修改条目。

http://www.ppmy.cn/embedded/51285.html

相关文章

AI 已经在污染互联网了。。赛博喂屎成为现实

大家好&#xff0c;我是程序员鱼皮。这两年 AI 发展势头迅猛&#xff0c;更好的性能、更低的成本、更优的效果&#xff0c;让 AI 这一曾经高高在上的技术也走入大众的视野&#xff0c;能够被我们大多数普通人轻松使用&#xff0c;无需理解复杂的技术和原理。 其中&#xff0c;…

AI视频智能监管赋能城市管理:打造安全有序的城市环境

一、方案背景 随着城市化进程的加速和科技的飞速发展&#xff0c;街道治安问题日益凸显&#xff0c;治安监控成为维护社会稳定和保障人民安全的重要手段。当前&#xff0c;许多城市已经建立了较为完善的治安监控体系&#xff0c;但仍存在一些问题。例如&#xff0c;监控设备分…

电子盖章软件能够盖骑缝章吗_电子骑缝章

电子盖章软件当然 能够盖骑缝章&#xff0c;并且有多种软件支持这一功能。以下是对电子盖章软件盖骑缝章功能的详细解释&#xff1a; 软件选择&#xff1a; 专门的电子签章软件&#xff0c;如Adobe Acrobat Pro DC、福昕高级PDF编辑器等&#xff0c;都支持在PDF文档上添加骑缝…

OSPF协议详解(一)

本文主要介绍OSPF的基础知识&#xff0c;主要从OSPF报文&#xff0c;OSPF原理、OSPF基本工作过程来介绍OSPF协议。 OSPF简述 OSPF&#xff08;开放式最短路径优先&#xff09;是广泛运用的一种动态路由协议。相比于静态路由协议&#xff0c;动态路由协议能够自适应网络环境的…

如何添加虚轴(AM400PLC)

1、添加虚轴 选择好后&#xff0c;选择点击添加。 2、虚轴循环周期任务 EtherCAT运动控制总线启用的时候&#xff0c;选择EtherCAT总线任务周期。

【STM32-新建工程-CubeMX】

STM32-新建工程-CubeMX ■ CubeMX 生产工程 ■ CubeMX 生产工程

SQL题:未完成率较高的50%用户近三个月答卷情况

SQL题&#xff1a;未完成率较高的50%用户近三个月答卷情况 这是一道牛客网上SQL进阶图库中的一道困难题目&#xff0c;个人花了近两个小时才通过所有用例。之所以想记录下来是因为这道题算是一个很考验基本功的题目&#xff0c;也不乏一些SQL中的技巧。下面我们逐步分析&#…

2.java pom.xml 添加配置说明

目录 1项目坐标&#xff1a; 2项目依赖&#xff1a; 3项目构建配置&#xff1a; 4项目属性&#xff1a; 5.项目信息&#xff1a; 6.项目分发管理&#xff1a; 7.项目插件配置&#xff1a; 8.项目依赖管理&#xff1a; pom.xml 是 Maven 项目的核心配置文件&#xff0c…