switch在Visual C中如何编译++它的优化程度和速度如何?
当我发现我只能在 C++ 的 switch
语句中使用数值时,我认为它和一堆 if-else
之间一定存在一些更深层次的区别。 s。
因此我问自己:
- 在运行速度、编译时优化和一般编译方面,
switch
与if-elseif-elseif
有何不同?我这里主要说的是MSVC。
As I found out that I can use only numerical values in C++'s switch
statements, I thought that there then must be some deeper difference between it and a bunch of if-else
's.
Therefore I asked myself:
- (How) does
switch
differ fromif-elseif-elseif
in terms of runtime speed, compile time optimization and general compilation? I'm mainly speaking of MSVC here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
开关通常被编译为跳转表(通过比较来找出要运行的代码),或者如果不可能,编译器仍可能对比较重新排序,以便在值之间执行二分搜索(log N比较)。 if-else 链是线性搜索(尽管我认为,如果所有相关值都是编译时积分常量,则编译器原则上可以执行类似的优化)。
A switch is often compiled to a jump-table (one comparison to find out which code to run), or if that is not possible, the compiler may still reorder the comparisons, so as to perform a binary search among the values (log N comparisons). An if-else chain is a linear search (although, I suppose, if all the relevant values are compile-time integral constants, the compiler could in principle perform similar optimizations).
Switch 语句通常是编译器优化的常见来源。也就是说,如何处理它们取决于您在编译器上使用的优化设置。
编译 switch 语句的最基本(未优化)方法是将其视为
if ... else if ...
语句链。编译器优化开关的常见方法是将其转换为 跳转表,它看起来像:此方法更快的原因之一是条件语句内的代码较小(因此,如果条件预测错误,指令缓存损失较小)。此外,“失败”情况的实现变得更加简单(编译器省略了
goto end
语句)。编译器可以通过创建指针数组(指向由标签标记的位置)并使用您要切换的值作为该数组的索引来进一步优化跳转表。这将消除代码中几乎所有的条件(除了验证您要切换的值是否与您的情况之一匹配所需的任何条件)。
需要注意的是:嵌套跳转表很难生成,有些编译器甚至拒绝尝试创建一个。因此,如果最大优化代码对您很重要,请避免将
switch
嵌套在另一个switch
中(我不能 100% 确定 MSVC 特别是如何处理嵌套的>switch
es,但编译器手册应该告诉你)。Switch statements are often a common source of compiler optimization. That is, how they are treated depends on the optimization settings you use on your compiler.
The most basic (un-optimized) way of compiling a switch statement is to treat it as a chain of
if ... else if ...
statements. The common way that compilers optimize a switch is to convert it to a jump table which can look something like:One reason this method is faster is because the code inside the conditionals is smaller (so there's a smaller instruction cache penalty if the conditional is mis-predicted). Also, the "fall-through" case becomes more trivial to implement (the compiler leaves off the
goto end
statement).Compilers can further optimize the jump table by creating an array of pointers (to the locations marked by the labels) and use the value you are switching on as an index into that array. This would eliminate nearly all of the conditionals from the code (except for whatever was needed to validate whether the value you are switching on matches one of your cases or not).
A word of caution: nested jump tables are difficult to generate and some compilers refuse to even try to create one. For that reason, avoid nesting a
switch
inside anotherswitch
if maximally-optimized code is important to you (I'm not 100% sure how MSVC in particular handles nestedswitch
es, but the compiler manual should tell you).