当您更改函数的Big O执行时间时,该怎么称呼?


19

假设我有一个可以O(n^2)及时对数据库进行排序的函数。我想对其进行重构,以使其能够O(n log(n))及时运行,并且这样做,我将更改操作的基本运行方式,同时保持返回值和输入相等。

我怎么称呼这种重构活动?

“加速优化”似乎不太正确,因为您可以在不改变算法执行速度的情况下使算法运行得更快。

“简化”似乎也不对。

我怎么称呼这项活动?

更新资料

我能找到的最佳答案是减少渐近时间的复杂度。


修改后,在大多数用例中,算法是否有望更快?需要注意的是,有时即使达到预期的平均性能命中率,也可以改用更高级别的复杂度类,只是为了获得更一致的性能行为。
Nat

22
这不是重构
theonlygusti

6
严格来说,O(log(n))及时运行的功能也要及时运行O(n^2)。的意思O(n^2)是“增长不会快于二次方”。您可能是说Theta(log(n)),意思是“增长速度与log(n)” 一样快。en.wikipedia.org/wiki/...
Džuris

4
<pedantic>您没有更改函数的大执行时间。函数是域和共域之间的关系,并且独立于您对实现的微弱尝试而存在。相反,您发现了一种性能更好的算法,该算法实现了功能</ pedantic> <human> good job </ human>
emory

5
@theonlygusti:取决于。如果该函数先前对复杂性做出了保证,那么它就没有重构。如果它不能保证任何事情,那就是重构。如果它甚至明确表示不做担保,那它就是重构。
菲涅尔

Answers:


44

通常将其称为“性能优化”,但我不会将其称为“重构”,因为该术语通常是指代码中的更改,这些更改不会更改其可见行为。Big-O的变化绝对是我所称的明显变化。

这样,我将更改操作的基本方式

在这种情况下,您的优化就是对该功能的重写。并不是每个优化都必须重写,即使它更改为“ Big-O”,有时也仅需进行很小的更改即可实现这种改进,但是即使那样,我也不愿意为此使用术语“重构”。往往给人关于变化本质的错误印象。

编辑:我检查了Fowler的重构列表,在这约100个命名的重构中,最后一个称为“替代算法”。因此,如果我们将此作为规范性参考,则会有一个很小的灰色区域,其中所描述形式的优化可能被称为一种特殊的重构(但恕我直言,这不是典型的重构)。还要注意,Fowler进行所有重构的目标始终是在不重写现有代码的情况下着眼于现有代码的可维护性和可扩展性来改进设计,并且显然不是性能优化。


10
真?我认为除非需求发生变化,否则重构是正确的。所以..如果该函数被称为BubbleSort,则为否,但如果其只是排序,则为是
Ewan

3
@Ewan是的,从法律上讲,重构可以是一种性能优化,但是前者过于笼统,不能适当地反映变更的影响。
Deduplicator

1
我是一位发明并创造了重构的人(Fowler?)的早期演讲者,整个想法与自动编程和可验证的代码改进相关,这些代码对输入和输出均无影响。
Sentinel

1
@史蒂夫。同意 我只是在达成共识,即Big O改进代表算法改进,而不是改进这些算法的表示或维护方式。换句话说,该活动是重写
哨兵报

1
@Steve:是的,我知道,因此想在我的答案中添加注释。我的编辑只是一个注释,目的是要弄清楚一个小的灰色区域。
布朗

13

我不认为有一个标准术语,尽管改进了,但通常使用的是优化,或者加快速度也将是正确的,这说明您在谈论代码更改而不是硬件更改。


7

正如其他人所说的,“优化”是改善算法性能的总称。但是,优化通常意味着改善常数因子。如果我想简明扼要地声明我已经降低了渐近(时间)复杂度,那么我会说我“提高了渐近性能”。有时人们将其描述为“改善缩放比例”,但如今这尤其模棱两可。

警告:减少渐近时间复杂度与在实际环境中进行优化不一定相同。通常,使用渐近非最佳算法,因为在输入范围内,程序实际上暴露于次优算法中,性能较好。


5

这将取决于上下文。

我通常会看到“修复二次运行时性能错误”。但是,是否值得修复(代码更改)取决于上下文。

请记住,数据库提供了许多工具来改善时间复杂度。例如,要从数据库中获取前N个结果,就这么说。将低效的kudge转换为内置的优化调用时,解释似乎是多余的。

我认为具有二次运行时间的算法值得代码审查(讨论)的原因并不是因为它慢(相对慢;相对于指数而言二次快),而是因为人类的直觉(例如您的客户或程序员对软件功能的天生不满意,因为它们对日常生活的期望不一而足,它偏离线性运行时的时间过长。

许多客户对软件性能的抱怨属于以下两类:

  • 根据估计的使用情况指定了整个系统(软件和硬件)。上周,一切运行正常,某些功能用了不到5秒钟的时间。本周,安装更新后,相同的功能将花费1分钟以上。

    • 这是与以前基准性能的比较。客户将未来的表现保持为人类时间尺度(从几秒钟到几分钟)的绝对标准。
  • 我向系统提交了100个工作。与单项工作相比,为什么要花400倍的处理时间?

    • 客户期望处理时间是线性的。实际上,客户不能理解或接受存在比线性慢的任务。

因此,如果两个都成立,那么客户将认为执行时间是一个错误:

  • 比线性慢
  • 引人注目(即,在给定典型任务大小的情况下,属于人类时间范围(大于秒或分钟))

解释二次运行时算法不会造成问题的合法参数(即,不应该更改代码):

  • 通常由这个二次运行时函数处理的任务的大小是有限的
  • 给定典型的大小范围,实际(绝对)执行时间仍然足够小,可以忽略
  • 如果用户实际尝试提交的任务足够大以至于无法引起注意,则该用户将收到一条消息,提示运行时间长
  • 系统的用户都是专家,因此他们知道自己在做什么。例如,API的用户应阅读API文档上的细则。

实际上,许多对典型应用程序开发有用的算法要比线性算法慢(大多数情况下为O(N log N),如排序),因此,大型软件实际上将尝试通过仅对相关部分进行排序来解决该问题。数据,或使用直方图(统计)过滤技术来达到类似效果。

这适用于软件客户,但是如果您也将软件库或API函数的用户也视为“客户”,那么答案仍然适用。


2

如果正确执行了原始算法(或任何不相关的错误),则“更改算法”“算法替换”,因为这样的更改意味着您正是在这样做;将具有不同时间复杂度的算法替换为先前使用的算法。

如果先前的时间复杂度是由于实现中的错误引起的(例如,说您不小心将序列上的内部循环的起点重置为原来应为O(n)的值变为O(n 2)),则“二次成本错误”或类似内容。

有一个重叠之处,在这种情况下,如果您从一开始就知道可以在O(n)时间和O(n 2)时间是错误操作,则,或者您首先在O(n 2)时间内有意实现了它,然后意识到它仍然可以正常工作而无需重置起点,因此用O(n)算法代替了O(n 2)算法。


1

速度优化一个或多个数量级。尽管这是数学上不正确的语言,但它最好地传达了更改订单的想法。

改进了可伸缩性。也听到了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.