就目前而言,此问题不适合我们的问答形式。我们希望答案能得到事实、参考资料或专业知识的支持,但此问题可能会引发辩论、争论、投票或更长时间的讨论。如果您认为此问题可以改进并可能重新讨论,请visit the help center寻求指导。
9年前就关门了。
下面是C++的代码:
#include <iostream>
int main(int argc, const char * argv[])
{
goto line2;
line1:
std::cout << "line 1";
goto line3;
line2:
std::cout << "line 2";
goto line1;
line3:
std::cout << "line 3";
goto line4;
line4:
std::cout << "Hello, World!\n";
return 0;
}
如果我做了一个更大的程序,比如说10,000行代码,我决定永远不使用我自己编写的函数,我只使用goto
语句。我只使用全局变量。我在最佳实践方面有点疯狂,但它是为了一个非常特定的目的。问题是,使用goto
语句进行跳转是否有效?如果我有1000个goto
标签会怎样?goto
语句是否直接转换成机器代码,告诉计算机只需跳转到不同的内存地址?与调用函数的成本相比,这样跳转的成本是否更低?
我想知道,因为我想写一个非常有效的程序来做一些计算,我需要非常有效,而不诉诸汇编/机器代码。
不用告诉我这在维护、代码的可理解性、最佳实践方面是个坏主意,我非常清楚这一点,我只是希望得到这个问题的答案。我不想在使用函数调用好还是使用goto
好之间进行任何辩论。
为了澄清这个问题,我关心的是在一个10,000行的程序中使用goto
,它与使用函数的传统程序相比如何。有多种方法可以比较和对比这两个程序,例如CPU缓存的性能如何。如果没有函数调用,它会给予什么样的节省?如果没有调用堆栈,这将如何影响CPU缓存,因为CPU缓存通常会使堆栈保持关闭状态。因此,是否会出现由于该高速缓存未被正确使用而导致性能下降的情况?就时间效率而言,调用函数与跳转相比的实际成本是多少?在效率方面有很多方法可以比较和对比这两种编程风格。
6条答案
按热度按时间oxf4rvwz1#
后藤语句是否直接转换成机器代码,告诉计算机跳转到不同的内存地址?
是的,我知道
与调用函数的成本相比,在机器中这样来回跳跃的成本是否更低?
是的,我知道
然而,当编译器看到一个函数调用时,它并不需要真正生成代码来调用函数。它可以把函数的内核直接插入到调用的位置,甚至不需要跳转。因此,调用函数可能会更高效!
此外,代码越小,效率越高(一般来说),因为它更适合CPU缓存。编译器可以看到这一点,并可以确定当函数很小时,最好将其内联,或当函数很大时,最好将其分离,使其成为一个真实的的函数。以生成最快的代码(如果您将其设置为生成尽可能快的代码)。您看不到这一点,所以您进行猜测,并且可能猜错。
这些只是一些显而易见的优化。编译器可以做很多其他的优化。让编译器来决定吧。它比你聪明。它比我聪明。编译器知道所有的。说真的,Cthulhu可能是一个编译器。
你说不要,但我要说:我强烈建议你在决定这么做之前分析你的代码,我几乎可以保证这不值得你花时间。编译器(大多数接近AI级别的智能)可能会生成 * 与常规函数调用 * 一样快或更快的代码,更不用说维护方面了。
ymdaylpp2#
后藤语句是否直接转换成机器代码,告诉计算机跳转到不同的内存地址?
差不多吧。
与调用函数的成本相比,在机器中这样来回跳跃的成本是否更低?
函数调用也会进行类似的跳转,但是在跳转之前,你必须为新函数设置新的堆栈帧,根据调用约定推送参数,最后设置返回值并展开。是的,不这样做可能会更快。
我有点疯了
是的,我知道
iq3niunx3#
1)* 问题是,使用后藤语句进行跳转是否有效?如果我有1000个goto标签会怎样?*
从你的4个
goto
标签的小例子中,你来回跳**,不,它在性能方面是没有效率的。为了避免函数调用机制的开销,这个方法禁用了编译器自动为你做的许多其他优化。我没有列出它们,但是this值得一阅读。2)* 后藤语句是否直接转换为机器代码,告诉计算机只需跳转到不同的内存地址?*
是(正如其他人正确指出的那样)
3)* 与调用函数的成本相比,在机器中这样来回跳转的成本是否更低?*
是的,只有当你的编译器是史前的,并且没有任何优化机制的时候,否则就不是。
我说的不是最佳实践。
c90pui9n4#
是的,从后藤生成的机器码将是一个直接的JUMP,而且这可能比函数调用更快,因为不需要对堆栈做任何事情(尽管没有任何变量传递的调用将以这样一种方式被优化,它可能同样快)。
当这个代码不起作用时,或者当其他人不得不维护它时,上帝会帮助你。
odopli945#
很难精确地回答你的查询,这取决于你的程序的复杂性和后藤语句的使用。
后藤语句等同于无条件跳转指令(如jmp)。goto的作用域将在文件内。
里奇建议避免使用后藤语句,如果仍然想/必须使用goto语句,则在自顶向下方法中使用它,而不要在自底向上的方法中使用它。
这些都是教科书上的细节。
实际上,你应该非常清楚在哪里使用后藤语句,以及在goto跳转之后你的程序流将在哪里,否则就像你提到的1000个goto语句一样,你将很难决定程序流,忘记其他的。所以进一步改进你的程序将非常非常困难。
还有很多其他的工具,如循环,条件语句,中断和继续语句,函数等,以帮助您避免这样的问题。
希望能帮上忙。
nwwlzxa76#
简而言之,'后藤'语句可能是高效的,但这就是它们真正的使用方式。(C++ from the GROUND UP),“没有任何编程情况需要使用后藤语句--它不是使语言完整所必需的一项。”许多程序员不喜欢goto语句的主要原因是后藤语句会使代码混乱和/或使代码难以阅读,因为,按照名称,goto语句可以从一个地方跳到另一个地方。尽管如此,有时候goto语句可以减少混乱并使代码更有效,但这完全取决于你如何使用它们以及它们所使用的上下文。就个人而言,我建议使用函数调用,而不是使用几个goto语句;其他人可能不同意。