将优化保留在本地,使其清晰可见,很好地进行文档记录,并可以轻松地就源代码和运行时性能而言,将优化版本彼此之间以及未优化版本之间进行比较。
完整答案
如果这样的优化真的是那么重要你的产品,那么你需要知道,不仅为什么之前的优化是有用的,但也能帮助开发者提供足够的信息,知道他们是否会在将来有用。
理想情况下,您需要将性能测试纳入构建过程中,以便找出新技术何时使旧的优化无效。
记得:
程序优化的第一条规则:不要这样做。
程序优化的第二条规则(仅适用于专家!):还不要这样做。”
-迈克尔·杰克逊
为了知道现在是否是时候,需要进行基准测试。
正如您所提到的,高度优化的代码的最大问题是难以维护,因此,您需要尽可能地将优化部分与未优化部分分开。无论是通过编译时链接,运行时虚拟函数调用还是两者之间的操作都无关紧要。重要的是,在运行测试时,您希望能够针对当前感兴趣的所有版本进行测试。
我倾向于以这样一种方式构建系统,即可以始终使用生产代码的基本未优化版本来理解代码的意图,然后与之一起构建不同的优化模块,其中包含一个或多个优化版本,无论在何处都明确记录优化版本与基准不同。运行测试(单元和集成)时,可以在未优化的版本和所有当前优化的模块上运行它。
例
例如,假设您具有快速傅立叶变换功能。也许您在中有一个基本的算法实现fft.c
并在中进行了测试fft_tests.c
。
然后是奔腾,您决定fft_mmx.c
使用MMX指令实现定点版本。后来奔腾3来临时,你决定添加它使用一个版本的SIMD流指令扩展在fft_sse.c
。
现在,您想添加CUDA,所以添加fft_cuda.c
,但是发现您使用了多年的测试数据集,CUDA版本比SSE版本慢!您进行了一些分析,最终添加了一个100倍大的数据集,并且可以达到预期的速度,但是现在您知道使用CUDA版本的设置时间非常重要,对于较小的数据集,您应该使用算法,无需支付设置费用。
在每种情况下,您都实现相同的算法,所有算法都应以相同的方式运行,但在不同的体系结构上运行效率和速度将有所不同(如果它们将完全运行)。但是,从代码角度来看,您可以比较任何一对源文件,以找出为什么以不同的方式实现同一接口的原因,通常,最简单的方法是引用未优化的原始版本。
对于OOP实现,所有这些都是相同的,其中实现未优化算法的基类和派生类实现不同的优化。
最重要的是保持了相同的东西都是一样的,这样的差异是显而易见的。