我是新来的,如果我以错误的方式做了这个帖子,请道歉.
我想知道是否有人可以解释为什么C函数调用这么慢?
关于递归斐波那契的标准问题很容易给出一个浅薄的答案,但如果我尽可能深地了解"更深层次"的理由,我将不胜感激.
谢谢.
编辑1:抱歉这个错误.我误解了维基上的一篇文章.
当你进行函数调用时,你的程序必须在堆栈上放置几个寄存器,可能会推送更多的东西,并弄乱堆栈指针.这就是所有可能"慢"的东西.实际上,这很快.在x86_64平台上大约有10个机器指令.
如果您的代码稀疏且功能非常小,那么速度很慢.这就是Fibonacci函数的情况.但是,您必须在"慢速调用"和"慢速算法"之间做出改变:使用递归实现计算Fibonacci套件几乎是最慢的直接方式.函数体中涉及的函数几乎与函数序言和结尾(推送和弹出发生的地方)相同.
在某些情况下,调用函数实际上会使代码整体更快.当您处理大型函数并且您的寄存器很拥挤时,编译器可能会花费大量时间来决定存储数据的寄存器.但是,在函数调用中隔离代码将简化编译器决定使用哪个寄存器的任务.
所以,不,C调用并不慢.
根据您在评论中发布的其他信息,似乎令您困惑的是这句话:
"在支持迭代循环结构的语言(如C和Java)中,由于管理堆栈所需的开销和函数调用的相对缓慢,通常会有大量的时间和空间成本与递归程序相关联;"
在递归实现斐波纳契计算的上下文中.
这就是说,递归函数调用比循环慢,但这并不意味着函数调用一般很慢或者C中的函数调用比其他语言中的函数调用慢.
Fibbonacci生成自然是递归算法,因此最明显和自然的实现涉及许多函数调用,但也可以表示为迭代(循环).
特别是斐波纳契数生成算法具有称为尾递归的特殊属性.尾递归递归函数可以轻松自动地转换为迭代,即使它表示为递归函数.有些语言,特别是递归很常见且迭代很少的函数式语言,可以保证它们能够识别这种模式并自动将这种递归转换为"引擎盖下"的迭代.一些优化的C编译器也会这样做,但不能保证.在C中,由于迭代既是常见的又是惯用的,并且由于尾部递归优化不一定由编译器为您完成,因此最好将其显式地编写为迭代以实现最佳性能.
因此,相对于其他语言,将此引用解释为对C函数调用速度的评论,将苹果与橙子进行比较.所讨论的其他语言是可以采用某些函数调用模式的语言(这些模式恰好发生在fibbonnaci数字生成中)并自动将它们转换为更快的内容,但速度更快,因为它实际上根本不是函数调用.