与调用函数相比,goto语句效率高吗?
Are goto statements efficient when compared to calling functions?
我这里有下面的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;
}
如果我写了一个更大的程序,比如说10000行代码,我决定我永远不会使用我自己写的函数,我只使用goto
语句。我只使用全局变量。我在最佳实践方面有点疯狂,但它有一个非常具体的目的。问题是,用goto
语句来跳来跳去是否有效?如果我有1000个goto
标签呢?
是否goto
语句直接翻译成机器码,告诉计算机只是跳转到不同的内存地址?与调用函数的成本相比,像这样在机器中跳来跳去的成本是否更低?
我想知道,因为我想写一个非常高效的程序来做一些计算,我需要非常高效,而不需要诉诸汇编/机器代码。
不必告诉我这在维护、代码的可理解性、最佳实践方面是一个坏主意,我非常清楚,我只是希望有一个问题的答案。我不想争论到底是使用函数调用好还是使用goto
好。
为了澄清这个问题,我关心的是,在这种情况下,仅在10,000行程序中使用goto
s,它将如何与使用函数的传统程序进行比较。有多种方法可以比较和对比这两个程序,例如CPU缓存如何执行。如果没有函数调用,它会提供什么样的节省?如果没有调用堆栈,这将如何影响CPU缓存,因为CPU缓存通常保持堆栈接近。是否存在这样一种情况,即由于缓存没有被正确利用而可能产生负面的性能影响?调用一个函数的实际代价是什么,与时间效率方面的跳转相比。在效率方面,有很多方法可以比较和对比这两种编程风格。
goto语句直接翻译成机器码,告诉计算机只是跳转到一个不同的内存地址吗?
是的。
与调用函数的成本相比,像这样在机器中跳来跳去的成本更低吗?
是的。
但是,当编译器看到函数调用时,它不必实际生成代码来调用函数。它可以把函数的核心放在调用的地方,甚至不需要跳转。所以调用函数会更有效率!
此外,代码越小,效率越高(一般来说),因为它更有可能适合CPU缓存。编译器可以看到这一点,并可以确定何时函数很小,最好内联它,或者何时函数很大,最好将其分离并使其成为一个真正的函数,以生成最快的代码(如果您设置为生成最快的代码)。你看不见这个,所以你猜,很可能猜错了。
这些只是一些明显的。编译器还可以做很多其他的优化。让编译器来决定。它比你聪明。它比我聪明。编译器知道所有。说真的,克苏鲁可能是个编译器。
你说不要这样做,但我要说:我强烈建议你在决定这样做之前,对配置你的代码,我几乎可以保证这不值得你花时间。编译器(大多数都接近ai级别的智能)可能会生成与常规函数调用一样快或更快的代码,更不用说维护方面了。
是否将goto语句直接转换为机器代码告诉计算机跳转到一个不同的内存地址?
差不多。
在机器上像这样跳来跳去成本更低吗与调用函数的代价相比?
函数调用将进行非常类似的跳转,但在跳转之前,必须为新函数设置新的堆栈框架,根据调用约定推入参数,最后设置任何返回值并展开。是的,也许不这样做会更快。
我有点疯狂
是的。
1) 问题是,使用goto语句跳转是否有效?如果我有1000个goto标签呢?
从您的4个goto
标签的小示例中,您来回跳转,不,它在性能方面效率不高。为了避免函数调用机制的开销,这个方法禁用了编译器会自动为您做的许多其他优化。我不列出它们,但这篇文章值得一读。
2) goto语句是否直接转换为机器代码,告诉计算机只是跳转到不同的内存地址?
YES(正如其他人正确指出的)
3) 与调用函数的成本相比,像这样在机器中跳来跳去的成本是否更低?
是的,只有当你的编译器是史前的,并且没有任何内置的优化机制。否则没有。
我说的不是最佳实践…
是的,从goto生成的机器码将是一个直接的JUMP。这可能会比函数调用快,因为不需要对堆栈做任何操作(尽管没有任何要传递的变量的调用将以这样一种方式进行优化,它可能会一样快)。
当这段代码不能正常工作时,上帝会帮助你的。或者当别人需要维护它的时候。
很难精确地回答您的查询,这取决于您的程序的复杂性和在其中使用goto语句。
goto语句相当于无条件跳转指令(如JMP)。goto的作用域将在文件内。
Ritchie建议避免使用goto语句,如果仍然想/必须使用goto语句,那么在自上而下的方法中使用它,不要在自下而上的方法中使用它。
这些都是课本上的细节。
实际上,你应该非常确定在哪里使用goto语句,在goto跳转之后你的程序流将在哪里,否则就像你提到的1000个goto语句一样,你也很难决定程序流,忘记其他的。因此,进一步改进你的程序将是非常非常困难的。
还有很多其他的工具,如循环、条件语句、break和continue语句、函数等,可以帮助你避免这些问题。
希望它能帮助.....
简而言之,'GoTo'语句可能是有效的,但这就是它们的实际使用方式。根据Herbert Schildt ( c++ from the GROUND UP)的说法,"没有任何编程情况需要使用goto语句——它不是使语言完整所必需的项。"最终,许多程序员不喜欢这个语句的主要原因是,goto语句往往会使您的代码混乱,并且/或者使代码很难阅读,因为goto语句可以从一个地方跳到另一个地方。话虽如此,有时候goto语句可以减少混乱并使代码更高效,但这完全取决于您如何使用它们以及使用它们的上下文。就个人而言,我建议使用函数调用,而不是几个goto语句;其他人可能不同意。
- 我的简单if-else语句是如何无法访问的代码
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么是0;C++中的有效语句
- Insert函数不适用于2 if语句C++
- 计算每个节点的树高,帮助我解释这个代码解决方案
- If语句未被求值C++
- 使数组的内存效率更高
- 内存效率高 map<pair<int,int>, set<int>> alternative
- 为什么同时使用一个赋值运算符处理复制和移动赋值效率不高
- 高斯的FFT;不确定在何处/如何插入值的打印语句
- 对于静态错误字符串,哪个的内存/性能效率更高,或者有替代方案
- 计算效率高的C++-一般阅读
- 5字节QByteArray的内存占用空间.5字节的quint64或QByteArray存储效率更高吗
- std::next_permutation实现解释似乎效率不高
- 应该在返回语句中使用std::move来提高效率吗?
- 矢量化图像块处理效率高
- 内存和处理效率高的多维数据结构C++
- 如果条件树切换语句效率问题
- 与调用函数相比,goto语句效率高吗?