我想这主要是关于破坏 C/C++ 优化器。
l_line1:
do_stuff(a, b);
l_line2:
do_other_stuff(n, m, o);
l_line3:
do_more_stuff(x);
如果标签在 if
block 中,如果这在运行中永远不会为真,那么性能会有差异吗?
if (debug_active) {
l_line1:
nextline = debugme(d1, d2, d3);
goto nextline_check;
}
do_stuff(a, b);
if (debug_active) {
l_line2:
nextline = debugme(d1, d2, d3);
goto nextline_check;
}
do_other_stuff(n, m, o);
if (debug_active) {
l_line3:
nextline = debugme(d1, d2, d3);
goto nextline_check;
}
do_more_stuff(x);
return;
nextline_check:
switch (nextline) {
case 1: goto l_line1;
case 2: goto l_line2;
case 3: goto l_line3;
default: DEB_ASSERT("Wrong line");
}
背景:
这些行是为源代码级调试器插入的。
包含所有这些 goto
的原因是因为代码是生成的(“原始”代码 - 从另一种语言翻译成 C/C++ - 这是第一个示例没有标签,第二个或多或少是调试选项生成的)。
如果您希望能够在调试期间跳过行,甚至更改下一条语句(两者都将由“用户”在函数 debugme
期间设置),您需要在每条语句和 goto 之前添加标签
这些标签依赖于返回(在本例中简化为返回代码)。
通过可移植代码获得更好性能的一般想法也很好(非可移植的建议也很高兴知道 - 至少对于 GCC 和 MSC)。
最佳答案
C 和 C++ 中的
标签和 goto
很像汇编程序中的标签和分支,这可能就是编译器生成的内容。请查看示例程序生成的代码,了解编译器的作用。如果这就是标签和 goto
的处理方式,那么“性能”就像在汇编程序中使用一样。
还应注意,编译器会在机器代码、循环和条件以及函数调用中生成很多 跳转,所有这些都会导致跳转,并且不会对性能造成太大影响。但是,编译器比您更了解底层 CPU 的细节,因此可以生成更好的跳转,不会像无条件跳转那样浪费指令缓存或停止指令管道,因此使用跳转可能确实会导致一个小的性能损失,但除非您使用标签和 goto
而不是循环或条件语句,否则它很少会引起注意。
也就是说,跳转会导致任何可能的性能问题,标签本身只是编译器中的占位符,因此它可以为机器代码生成正确的跳转偏移量。一旦您的程序通过了编译器,标签就不再存在于目标文件或生成的代码中。
最后是反对使用 goto
的常见建议。虽然它在少数 情况下可能有意义,但大多数程序员永远不会遇到goto
有意义的情况。简单地不要使用它,通常有其他语言结构更适合,或者至少更优化,至少更易于维护。
关于c++ - C/C++ 标签 (goto) 的数量如何影响性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38163371/