在最近与其他程序员的对话中,我断言“如果你不止一次编写相同的代码,重构该功能可能是一个好主意,这样就可以从每个地方调用一次。 “
我的程序员伙伴坚持认为,进行这些函数调用对性能的影响是不可接受的。
现在,我不是在寻找谁是对的验证。我只是想知道在重构之前我是否应该考虑函数调用的性能影响。
答案 0 :(得分:3)
“我的同事程序员伙伴坚持认为,这些函数调用对性能的影响是不可接受的。”
......正确的答案是“证明它。”
关于premature optimization的旧见解适用于此。任何不熟悉它的人都需要在受到更多伤害之前接受教育。
恕我直言,如果你没有这种态度,你宁愿花几个小时编写一个可以用于10秒以上切割和粘贴代码的例程,那么你就不应该称自己为编码器。
答案 1 :(得分:2)
如果代码不在一个被调用数百万次的循环中,在用户可能注意到差异的区域中,甚至不考虑调用开销的影响。一旦您满足这些条件,请继续进行分析,看看您的担忧是否合理。
答案 2 :(得分:2)
现代Java语言编译器无论如何都会内联某些函数调用。我的观点是,设计对于花费在函数调用上的几条指令来说更为重要。我能想到的唯一情况是在汇编程序中编写一些非常精细的代码。
答案 3 :(得分:1)
你需要问自己几个问题:
当然,这会帮助你晚上睡得更好吗? :)
答案 4 :(得分:1)
我敢打赌,有一段时间,调用外部方法或函数的性能成本需要关注,就像变量名称的长度和所有需要用尊重绩效影响。
随着过去二十年中处理器速度和内存资源的巨大增长,我建议这些问题不再像过去那样具有相关性。
我们已经能够使用长变量名一段时间,并且在大多数情况下调用外部代码的成本可能微不足道。
可能有例外。如果在大型循环中放置函数调用,则可能会看到一些影响,具体取决于迭代次数。
我建议在大多数情况下,您会发现将重构代码转换为离散函数调用的影响可以忽略不计。可能会有一些影响。但是,正确的重构测试将揭示这一点。在少数情况下,你的朋友可能是正确的。在剩下的大部分时间里,我建议你的朋友稍微坚持一下与大多数现代处理器和存储介质相比的做法。
答案 5 :(得分:1)
在关心任何其他开销时,您关心函数调用开销:当您的性能分析工具表明它是一个问题时。
答案 6 :(得分:0)
表示c / c ++系列:
通话的“费用”并不重要。如果它需要快速,你只需要确保编译器能够内联它。这意味着:
主体必须对编译器可见
身体确实小到足以被视为内联候选人。
该方法不需要动态调度
有几种方法可以打破这种默认能力。例如:
呼叫站点中已有大量指令计数。即使使用早期内联,编译器也可能会弹出一个简单的函数(即使它可能会生成更多的指令/更慢的执行)。早期内联是编译器在早期内联函数的能力,当它看到调用成本高于内联时。
递归
关于其原始意图,内联关键字在这个时代或多或少是无用的。但是,许多编译器提供了一种使用编译器特定指令恢复含义的方法。使用此指令(正确)有很大帮助。学习如何正确使用它需要时间。如果有疑问,请省略该指令并将其留给编译器。
假设您使用的是现代编译器,除非您也愿意为此特定程序进行汇编,否则没有理由避免使用该函数。
现在,如果表现至关重要,你真的有两个选择:
1)学会编写组织良好的速度程序。缺点:编译时间较长
2)保持一个写得不好的程序
我更喜欢1.任何一天。
(是的,我 花了很多时间编写性能关键程序)