我有一个关于如何以能够在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)
...
OR
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)
}
{
...
}
在性能方面哪一个更好?
如果您需要我更具体,请告诉我。
感谢任何帮助。
答案 0 :(得分:2)
现在我的问题是......它是否对表现有影响?
答案是否定的。与网络延迟相比,差异 100%不太可能导致速度减慢以及如何处理数据包发送/接收(缓冲,逻辑等)。我的建议是在优化任何事情之前设置并运行性能测量。
答案 1 :(得分:2)
我想在已经很好的答案中添加一个有趣的替代品和一些数字事实。
0.使用switch语句而不是if-chain
一条黄金法则可能是:永远不会自己做你的编译器可以为你做的事情(好多了)!
任何体面的编译器都可以使用跳转表轻松优化switch
语句:恒定时间内的1个操作将决定使用哪个case
代码。没有区别,如果它是10条消息或10 000条。更多关于jump tables。
当然这需要消息类型是常量。
1.如果您需要使用if-chains
,则有一些背景知识将int
与常量进行比较需要2个CPU指令:比较(CMP)和条件跳转(JNE)。采用现代处理器,大约1纳秒。对于良好的GBit以太网实现,网络延迟大约为30μs(30 000纳秒)。少于30 000条消息?别担心!
但是,如果您使用具有多个网络接口和多线程馈送架构的高性能服务器,请考虑性能两次:1GB-ethernet接口意味着每个接口每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-chain,达到500纳秒。
4.可读性和可扩展性
数百个条目的开关或ifchain非常难以阅读,因此容易出错。
更容易维护的替代方法可能是使用command design pattern在初始化期间构建一个命令表,其中消息类型将是索引。几乎和跳转表一样高效,但更容易维护。
答案 2 :(得分:1)
划分为子类别会更好。 此外,您可以使用开关盒。编译器将为您优化比较。