如何在 c++ 中提高 IF 语句性能

How to increase IF Statement performance in c++

本文关键字:IF 语句 性能 c++      更新时间:2023-10-16

我有一个关于如何以C++中获得最佳性能的方式执行我的 IF 语句的问题。我的问题可能看起来很基本,但我需要问。

假设我有一条消息要通过网络发送。 消息类型可能会有所不同。有许多类型的消息。

现在我的问题是,将这些信息分类为一组或将它们分为某些类别和子类别更好,以及它是否对性能有影响?

为了说明这一点,请考虑:

if (msg.Type == T1)
else if (msg.Type == T11)
else if (msg.Tye == T12)
...
else if (msg.Type == T120)
else if (msg.Type == T2)
else if (msg.Type == T21)
else if (msg.Tye == T22)
...
else if (msg.Type == T220)
...

if (msg.Type == T1)
{
    if (msg.Type == T11)
    else if (msg.Tye == T12)
    ...
    else if (msg.Type == T120)
}
else if (msg.Type == T2)
{
    if (msg.Type == T21)
    else if (msg.Tye == T22)
    ...
    else if (msg.Type == T220)
}
{
    ...
}

在性能方面,哪一个更好?

如果您需要我更具体,请告诉我。

任何帮助,不胜感激。

现在我的问题是...是否对表演有感情?

答案是否定的。与网络延迟以及处理数据包发送/接收的方式(缓冲、逻辑等(相比,这种差异 100% 不太可能导致速度变慢。我的建议是在优化任何内容之前设置并运行性能测量。

我想在已经很好的答案中添加一个有趣的替代方案和一些数字事实。

0.使用开关语句代替if链

一条黄金法则是:永远不要做编译器能为你做的事(好得多(!

任何像样的编译器都可以使用跳转表轻松优化switch语句:常量时间内的 1 个操作将决定使用哪个case代码。如果是 10 条消息还是 10 000 条消息,没有区别。 这里有更多关于跳转表的信息。

当然,这要求消息类型是常量。

1.一些背景,如果你需要使用if链

int与常量进行比较需要 2 个 CPU 指令:比较 (CMP( 和条件跳转 (JNE(。 使用现代处理器,它大约是 1 纳秒。 对于良好的 GBit 以太网实施,网络延迟约为 30μs(30,000 纳秒(。少于 30 000 条消息? 不要太担心!

但是,如果您在具有多个网络接口和多线程馈送体系结构的高性能服务器上工作,请考虑两次性能:1GB 以太网接口意味着每个接口平均每 8 纳秒处理 1 个字节。10GBEhternet即将到来。

2.只有几种消息类型

对于 M 个消息类型并且每种消息类型的概率相同,平均选择开销将约为 M/2 ifs(即 100 种类型 --> 50 纳秒(

如果某些消息类型比其他消息类型更频繁,请将它们放在链的开头以体验显著的改进。 例如,如果 50% 的消息对应于链的第一种类型,则平均开销将为 3/4+M/4 ifs(即 100 种类型 -> 26 纳秒(

3.具有更多类型

然后子组应该是组合的。 如果你有 G 组和 M 等概率消息类型,平均需要 G/2+M/G/2 ifs(即 1000 种类型,10 组 -> 55 纳秒,而简单的 if 链需要 500 纳秒(。

4.可读性和可扩展性

一个包含数百个条目的开关或 ifchain 非常难以读取,因此容易出错。

一种更易于维护的替代方法是使用命令设计模式在初始化期间构建命令表,其中消息类型将是索引。 几乎与跳台一样高效,但更易于维护。

划分

为子类别会更好。此外,您可以使用开关盒。编译器将为您优化比较。