我正在开展一个非常重要的大型性能关键项目。在为这个产品设计算法的过程中,我的雇主经常提醒我编写更“人性化”的代码,或者以更符合我们逻辑思维方式的方式编写代码。
虽然从一些不同的角度来看这对我有意义(例如易于理解/记忆,代码维护等),但我也想知道这种方法是否也可以预期会导致更优化的编译输出。
这可能是因为编译器是由人类编写的,而优化器通常用于识别熟悉的代码块吗?
我希望听到一些关于为什么会出现这种情况的想法。
答案 0 :(得分:1)
考虑两种不同的代码,库代码和应用程序代码。 库代码(如字符串类库)很可能在很多时候拥有程序计数器,如下所示:
while(some test){
massage some data, while seldom calling sub-functions
}
这种代码将受益于编译器优化。 (所以为了回答你的问题,人们编写这样的基准函数,编译器编写者将它们用作测试用例。)
另一方面,应用程序代码往往如下所示:
if (some test){
do a bunch of things, including many function calls
} else if (some other test){
do a bunch of things, including many function calls
} else {
do a bunch of things, including many function calls
}
在这种情况下,通过分支预测或循环剃须节省的时间可能是1个时间单位,比如,do a bunch of things...
可能花费10 ^ 2到10 ^ 8个时间单位,有或没有我/ O。
因此,编码优化此代码的好处往往会在噪声中完全丢失。
这并不是说它无法优化。 这只是编译器无法做到的 - 这是你的工作。
如果你想让后一种代码快速运行,最好的方法是找出调用堆栈中哪些代码行占用了很长的时间,如果可能的话,找到一种方法来避免这样做。 (Here's an example of a 43x speedup.)
答案 1 :(得分:0)
什么是“人类逻辑”可能因人而异。
例如,如果我是新手,根据书面指示执行任务,我会(通常),随着时间的推移,用心去学习一些任务,而对于其他人,我会回到说明只是因为任务不经常执行/太无聊或两者兼而有之。在相同情况下的其他人可能会或可能不会相似地运作,并且不确定他们将学习的任务将是我学到的任务。
对于编程,它的工作原理类似。有些人可能会以一种方式构建一个循环并在其中执行测试以便于阅读,而我可能出于性能原因在外面进行测试。什么更错,什么更正确?
人们普遍认为编译器会优化任何东西。这是真的,但正如我在另一篇文章中(大幅度地)写的那样,GIGO(Garbage In = Garbage Out)适用。编译器不是在真空中运行:给定一组规则,它们将对源代码执行安全优化,达到其(编译器)构造函数在代码优化中的想象力和能力。膨胀源代码将成为优化的膨胀机器代码。以同样的方式,精益和平均源代码将变得优化精益和平均机器代码。在关键的地方,可以提供它“感觉”的编译器源代码(是的!它们确实具有个性),在优化时非常舒适,并且生成的机器代码将会飞行。
我们都经历过表现不佳的软件。如果我们很幸运,我们经验丰富的软件表现非常出色。一个开发人员可以学习编写一段代码,该代码在与另一代码编写性能差的代码相同的时间内表现良好。