标签(goto)的数量如何影响性能?
C/C++ How does the number of labels (goto) influence performance?
我猜这主要是关于破坏C/c++优化器。
l_line1:
do_stuff(a, b);
l_line2:
do_other_stuff(n, m, o);
l_line3:
do_more_stuff(x);
如果标签在if
块内,如果在运行中不为真,性能是否有差异?
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
的处理方式,那么"性能"就像在汇编器中使用相同的。
goto
而不是循环或条件语句。
也就是说,是跳转导致了任何可能的性能问题,标签本身只是编译器中的占位符,因此它可以为机器码生成正确的跳转偏移量。一旦程序通过编译器,标签就不再存在于目标文件或生成的代码中。
最后是反对使用goto
的常用建议。虽然它在少数情况下可能是有意义的,但大多数程序员永远不会遇到goto
有意义的情况。简单地说,不要使用它,语言的其他结构通常会更适合,或者至少更优化,至少更易于维护。
我认为,通过"在运行中永远不为真",您承认变量debug_active
在运行时可以取true或false值——尽管在任何给定的运行中只有一个这样的值——换句话说,它不是编译时宏。考虑到这一点:
debugme
调用完全破坏,返回一个int,然后在nextline_check
的switch
中使用该int来动态选择要执行的下一个代码块。任何依赖于通过知道控制流来计算数据流的优化都将在那里失败。
第一个版本更好,但不是很多,因为当控制流无法确定时,标签也会混淆许多/所有优化,这在许多情况下是可能的。除非有一个debugme
/nextline_check
隐藏在你没有显示的地方——在这种情况下,同样的问题就会出现在第二个版本中。
(实际上,对于苹果与苹果的比较,我们需要看到第一种情况下的分派代码,就像您在第二种情况中提供的那样。)
在任何情况下,无论您做什么,生成的代码的"性能"都将非常糟糕(与优化的未检测的原始源代码相比)。您唯一的问题是:它是否糟糕到足以破坏您的调试器概念,因为它使用户感到沮丧,而不是使调试器提供的好处使他们满意?(注:就像一个简单的例子,优化器将不能在你的第二个版本中做的:它不能假设任何特定的值在语句开始的给定寄存器中(即,最初出现在源代码中的语句),因为它已经留在了前面的语句中。
我怀疑标签的数量是否有任何实际的性能影响,因为如果没有跳转到它们,就没有成本-它们只是可能的(符号)目的地,它们本身不会导致任何代码,甚至不会进入最终的目标文件。即使有东西跳转到它们,它们也很容易被跳转位置的常量所替换。但是,通过检查生成的asm,您应该能够轻松地验证或反驳这一点—您应该看到所有标签都消失了。
我是这样做的。不需要goto
if (! debug_active) {
// fast path when not debugging
do_stuff(a, b);
do_other_stuff(n, m, o);
do_more_stuff(x);
} else {
nextline = debugme(d1, d2, d3);
while ( true ) {
if( nextline == 1 ) {
do_stuff(a, b);
nextline = debugme(d1, d2, d3);
if( nextline < 2 ) continue;
}
if( nextline == 2 ) {
do_other_stuff(n, m, o);
nextline = debugme(d1, d2, d3);
if( nextline < 3 ) continue;
}
if( nextline == 3 ) {
do_more_stuff(x);
nextline = debugme(d1, d2, d3);
if( nextline < 4 ) continue;
}
break;
} // while
} // if
return;
- 数组中的不同浮点值会影响性能 10 倍 - 为什么?
- 为 lambda 分配名称会影响性能吗?
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 隐式转换函数的返回对象时是否会影响性能?
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- 性能 - 链接 C 尖锐和C++如何影响性能
- C 指针向量如何影响性能
- 公开类的内部组件,以防止编写过多代码和影响性能
- .NET 4,C ,IF..Else和Switch()如何影响性能
- 变量会影响性能吗
- 更改自动分配内存的范围是否会影响性能
- 如何修复不影响性能的"runtime error"?
- 返回间接类型化对象是否会影响性能
- 调用恒定复杂度O(1)5行函数会显著影响性能,原因如下
- 使用Pimpl的高级变体时可能会影响性能
- 功能原型设计会影响性能吗
- 在C/ c++中包含未使用的头文件会影响性能吗?
- 我可以在不影响性能的情况下将此宏更改为内联函数吗
- Dispatch_async在下面的代码中影响性能
- c++中的操作符重载如何影响性能