是为单元测试优化实践优化一个类,还是为时过早?

时间:2011-03-31 21:17:42

标签: unit-testing oop class optimization premature-optimization

我在StackOverflow上看到(并搜索过)关于过早优化的很多问题 - 街上的字是,它是所有邪恶的根源。 :P我承认我经常犯这个罪;我并没有真正以代码易读性为代价来优化速度,但我会使用似乎更适合任务的数据类型和方法以逻辑方式重写我的代码(例如在Actionscript 3中,使用类型化Vector而不是无类型数组对于迭代)如果我可以使我的代码更优雅,我会这样做。这通常有助于我理解我的代码,我通常知道为什么要进行这些更改。

无论如何,我今天想 - 在OOP中,我们推动封装,试图隐藏实现并提升界面,以便类松散耦合。我们的想法是制作一些有效的东西,而不必知道内部发生了什么 - 黑盒子的想法。

因此,这是我的问题 - 尝试在类级别深入优化代码是明智的,因为OOP促进了模块化?或者这是否属于过早优化的范畴?我想,如果你使用一种容易支持单元测试的语言,你可以测试,测试和优化类,因为它本身就是一个接收输入并生成输出的模块。但是,作为一个编写代码的人,我不知道等待项目完全完成以开始优化是否更明智。

供参考:我之前从未在团队中工作过,所以对于有这种经历的开发人员来说显而易见的事情可能对我来说很陌生。

希望这个问题适合StackOverflow - 我找不到另一个直接回答我的查询的问题。

谢谢!

编辑:考虑到这个问题,我意识到“profiling”可能是正确的术语,而不是“单元测试”;单元测试检查模块是否正常工作,同时分析检查性能。另外,我之前应该问过的问题的一部分 - 在创建它们之后对各个模块进行概要分析是否会在应用程序完成后减少时间分析?

我的问题源于我正在尝试的游戏开发 - 我必须创建模块,例如图形引擎,应该以最佳方式执行(不管它们是不同的故事:D )。在性能不太重要的应用程序中,我可能不会担心这一点。

5 个答案:

答案 0 :(得分:2)

  

我并没有真正以代码易读性为代价来优化速度,但是我将使用数据类型和方法以逻辑方式重写我的代码,这些数据类型和方法似乎更适合任务[...]并且我可以编写代码更优雅,我会这样做。这通常有助于我理解我的代码

这不是真正的优化,而是refactoring更清晰的代码和更好的设计*。因此,它是一件好事,它确实应该以小的增量连续实践。鲍勃·马丁叔叔(在他的书Clean Code中)推广了童子军规则,适用于软件开发:保持代码比你发现的更干净

所以回答你的标题问题,是的,重构代码使其单元可测试是一个很好的做法。其中一个“极端”是Test Driven Development,其中一个首先编写测试,然后添加使测试通过的代码。这样,代码从一开始就可以单元测试。

*不要挑剔,只是澄清常用术语并确保我们使用相同含义的相同术语是有用的。

答案 1 :(得分:1)

是的,我相信优化应该留作最后的任务(虽然很好地认识到在编写初稿时可能需要返回并优化的地方)。这并不是说你不应该迭代地重新计算事物,以维护代码中的顺序和清洁。这就是说,如果某些东西目前用于此目的并且不是对应用程序的要求拙劣,则应首先解决要求,因为最终它们是您负责交付的(除非要求包括最长请求时间或这些方面的东西)。我同意Korin的方法,如果时间允许优化你的心脏含量(或理论限制,以先到者为准),首先建立功能。

答案 2 :(得分:1)

过早优化是一件坏事的原因是:它可能需要花费很多时间,而且您事先并不知道最佳利用时间的可能性。

例如,您可能会花费大量时间来优化类,但却发现应用程序中的瓶颈是网络延迟或类似因素,这在执行时间方面要贵得多。因为在开始时你没有完整的图片,过早的优化会导致你的时间使用不够理想。在这种情况下,您可能更愿意修复延迟问题,而不是优化类代码。

答案 3 :(得分:1)

我坚信,由于性能优化,您应该从不降低代码可读性和良好的设计。

如果您正在编写性能至关重要的代码,则可以降低代码的样式和清晰度,但这对于普通的企业应用程序来说并不适用。硬件发展迅速,每天变得更便宜。最后,您正在编写将由其他开发人员阅读的代码,因此您最好做好它!

阅读经过精心制作的代码总是很美观,其中每个路径都有一个测试,可以帮助您了解应该如何使用它。我真的不在乎它是否比意大利面条替代品慢了50毫秒,它会做很多疯狂的东西。

答案 4 :(得分:1)

是的,您应该跳过针对单元测试的优化。需要时进行优化通常会使代码更复杂。瞄准简单。如果您针对单元测试进行优化,则实际上可能会对生产进行去优化。

如果单元测试中的性能非常糟糕,您可能需要查看您的设计。在应用程序中进行测试,以确定在优化之前性能是否同样差。

编辑:当处理的数据大小不同时,可能会发生去优化。对于使用数据集的类,最有可能发生这种情况。响应可能是线性的,但与几何和原始快速相比,原本很慢。如果单元测试使用一小组数据,则可以选择几何解决方案进行单元测试。当生产使用大量数据性能罐进入班级时。

排序算法是这种行为的典型案例,并导致去优化。许多其他算法具有相似的特征。

EDIT2:我最成功的优化是报告的排序例程,其中数据存储在内存映射文件的磁盘上。排序时间合理,数据大小适中,不需要磁盘访问。对于较大尺寸的数据集,处理数据可能需要数天。报告的初步时间显示;数据选择3分钟,数据排序3天,报告3分钟。对该类型的调查表明,它是一种完全未优化的冒泡排序(对于大小为n的数据集,n-1完全通过),大O符号大致为n平方。更改排序算法可将此报告的排序时间缩短为3分钟。我不希望单元测试覆盖这种情况,原始代码就像你可以获得的小集一样简单(快速)。对于非常小的集合,替换更复杂且更慢,但是使用更大的线性曲线更快地处理大集合,在大O表示法中n log n。 (注意:在我们有指标之前,没有尝试过优化。)

在实践中,我的目标是将例程的十倍改进,至少占模块运行时间的50%。使用55%的运行时间为例程实现此级别的优化将节省50%的总运行时间。