user-0 提问: 调用一个函数的开销大吗？

回复:
user: user-1
content: 函数调用的开销，在99%的情况下不用考虑，因为从我从十多年来来没有遇到过，也没有朋友遇到过。

user: user-2
content: 函数调用没有被强调，所以不会有太大的问题。 较真到汇编层，那肯定是越少指令越好，但这个要求对应用程序开发意义不大，不会影响体验。而且，开发效率，可一直性会比CPU执行效率更重要。   所以，需要在可比的环境中选择更好的方案。 比如，我有一个函数指针，有两种方法调用： 一种是使用if(p!=null)判断后调用，另一种是在初始化的时候使用p=&f，让p始终不为空，而f只是一个空函数。  上述这种情况需要应该是可以测试验证的，可以测量出那种方案更好。

user: user-3
content: 引用 楼主 screen12 的回复:书上说，调用函数有一定的时间开销。所以如果函数很简单，可以把它定义为内联函数，这样实际上并没有函数调用，只是把代码嵌入到调用的地方而已。  我想问的是：函数调用的开销有多大？按照我的想象：就是把几个参数压入堆栈，然后一个跳转指令，就开始执行了。执行完了，再跳转回来，似乎开销并不大。  我们算一笔帐，现在的CPU主频有几个G，就算2G吧，那一秒钟就有20亿个时钟周期，把几个参数压入堆栈需要花多长时间？一个参数只需要一到两个最后两到三个时钟周期就够了，再加上跳转指令，最后再跳回来。就算总共20个时间周期吧，那也就亿分之一秒就完成了。  这样算来，函数调用的开销并不大。  我担心的是函数调用是不是还有别的开销，是不是要建立新的堆栈？或者还有什么别的我不知道的开销？  请达人指教，函数调用的时间开销大不大？亿分之一秒能完成吗？  这个问题需要一分为二的看，确实有开销。是不是大，需要看实际运行场景。赵老师说的离开profiling谈优化就是耍流氓

user: user-4
content: 看情况            没有总比有耗时间

user: user-5
content: 函数调用的开销优化，通常是逼不到那个份上的，只要知道内联可以优化，等你遇到了再说。

user: user-6
content: 另外也看到函数的好处： 接口和实现分离，针对接口编程， 抽象性更好。

user: user-6
content: 函数调用的开销： 参数的入栈出栈（内存读写）， 跳转指令带来的cache miss甚至页面换入换出， 但是总的来说不大。但是如果函数调用出现在热点路径上， 则不得不考虑了。 但是应防止过早优化，盲目优化， 优化应该基于profiling。

user: user-0
content: 引用 13 楼 my_live_123 的回复:回答一个问题：不需要建新堆栈！程序加载运行时候，堆栈已经建立完成。OS分配固定大小栈。直到程序消亡才收回这部分栈所占内存。效率是个相对而言的话题，具体问题具体分析，折中吧！  如果不需要建立新的堆栈，那我认为，我主贴的问题答案就是：函数调用的开销不大。  因为函数调用，翻译成汇编语言，就是把参数压入堆栈的过程，几个PUSH指令，函数结束后几个POP指令，每个指令只需要二、三个时钟周期，这还是早期的8086处理器，现在的CPU更高级，恐怕不到二、三个时钟周期了。  至于局部变量，好象就是在堆栈中留下一定的空间，这个通过调整ESP指针就行了，一条指令即可。  后面一些网友谈到跳转指令让cache失效的问题，那个是高级问题，就算失效了，再取嘛，最多不从cache中取，而从内存中取，现在的内存都是几百M的频率，也慢不到哪里去。  我的程序中，函数调用只有几十次，最多一百来次，这样看来，函数调用的开销几乎可以忽略。那我就决定使用函数调用了。不使用内联函数，那个太麻烦。

user: user-7
content: 引用 16 楼 FrankHB1989 的回复:C本来就没说函数调用靠什么实现。随实现高兴。就是非得要用hash实现调用栈也没办法。 只不过一般直接拿体系结构支持的栈来偷懒了。这个情况下也没必要动不动另外分配栈。 cache嘛当然是个问题，但是对cache影响有多大本来就很难说，视具体函数而定。 另外别忘了对于C而言所谓的“调用”是包括函数体里面的开销的…… 所以一般而言这样的问题没意义。 如果只是考虑内联，记住编译器一般比你清楚就行了。 这里最有营养的搞不好还是赵老湿说的……

user: user-8
content: C本来就没说函数调用靠什么实现。随实现高兴。就是非得要用hash实现调用栈也没办法。 只不过一般直接拿体系结构支持的栈来偷懒了。这个情况下也没必要动不动另外分配栈。 cache嘛当然是个问题，但是对cache影响有多大本来就很难说，视具体函数而定。 另外别忘了对于C而言所谓的“调用”是包括函数体里面的开销的…… 所以一般而言这样的问题没意义。 如果只是考虑内联，记住编译器一般比你清楚就行了。 这里最有营养的搞不好还是赵老湿说的……

user: user-9
content: 引用 16 楼 FrankHB1989 的回复:C本来就没说函数调用靠什么实现。随实现高兴。就是非得要用hash实现调用栈也没办法。 只不过一般直接拿体系结构支持的栈来偷懒了。这个情况下也没必要动不动另外分配栈。 cache嘛当然是个问题，但是对cache影响有多大本来就很难说，视具体函数而定。 另外别忘了对于C而言所谓的“调用”是包括函数体里面的开销的…… 所以一般而言这样的问题没意义。 如果只是考虑内联，记住编译器一般比你清楚就行了。 这里最有营养的搞不好还是赵老湿说的……++

user: user-10
content: 回答一个问题：不需要建新堆栈！程序加载运行时候，堆栈已经建立完成。OS分配固定大小栈。直到程序消亡才收回这部分栈所占内存。效率是个相对而言的话题，具体问题具体分析，折中吧！

user: user-11
content: 引用 14 楼 lm_whales 的回复:这里涉及的东西太多了 对于现代CPU来说，跳转会造成指令预取队列失效，所以优化掉跳转，很多时候能够加快代码执行效率。 但是任何事情都不是绝对的，就像#12楼所述Cache失效，也会影响效率 不过一般跳转，也有可能造成Cache失效， 所以没法直接笼统的确定，何种情况效率更高。 一般都是都是根据具体环境决定的。 多数情况下，inline 比非inline 效率高 但是并非总是这样。 ++

user: user-9
content: 这里涉及的东西太多了 对于现代CPU来说，跳转会造成指令预取队列失效，所以优化掉跳转，很多时候能够加快代码执行效率。 但是任何事情都不是绝对的，就像#12楼所述Cache失效，也会影响效率 不过一般跳转，也有可能造成Cache失效， 所以没法直接笼统的确定，何种情况效率更高。 一般都是都是根据具体环境决定的。 多数情况下，inline 比非inline 效率高 但是并非总是这样。

user: user-7
content: 无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

user: user-12
content: 内联之后，代码膨胀，就有可能造成cache失效，完全可能比调函数更慢。 所以，关于优化，几乎所有的语言都是2条建议 1 不要优化 2 （仅供专家参考）不要优化。

user: user-13
content: 引用 8 楼 zhao4zhong1 的回复:无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！ ++

user: user-14
content: 一个就没什么了啊！多而频繁的话就不好说了！

user: user-15
content: 函数调用的开销大不大，是和函数执行时间对比的。  假如函数的调用需要1个时钟周期，但是执行时间也只是用了1个时钟，就是说一个函数居然有50%的时间是用在调用上面的。如果这个函数调用得非常频繁，这个的效率就太低了，一个程序浪费50%的时间用在调用函数上，你不觉得很白痴吗？为什么这样的函数不写成内联函数？  这么简单的道理都不明白？

user: user-16
content: 引用 5 楼 screen12 的回复:[quote=引用 3 楼 baichi4141 的回复:] 一个科学运算程序需要循环十亿次，每次运行十亿分之五秒得出本次结果。 然后楼主往这个循环里添加了三个函数调用，每次调用花费亿分之一秒。 楼主说这开销大不大？  即使是一个需要极高运行效率的程序，大多数代码也不需要优化 最关键的那一部分代码，别说函数调用了，有时甚至要直接写汇编来取代编译器自动优化 函数调用除了把参数压入堆栈，跳转以外，还没有别的开销？比如要不要建立一个自己的堆栈？  如果没有别的工作了，我觉得函数调用开销不太大。调用个几千次也没什么大不了。[/quote] 参数压入堆栈，这个本身开销就很大，因为有内存的读写操作，函数有自己的栈桢，调用个几千次可能是不大，如果每秒上百万次调用，你觉得大不大。