效率/算法与系统规范

时间:2008-10-20 04:00:47

标签: algorithm

我们都在谈论算法的效率,它取决于输入大小 - 基本上。

运行算法的当前计算机的系统规格如何?在Core 2 Duo 2.6 GHZ,4 GB RAM计算机或P-2,256 MB RAM计算机中运行不同的排序算法会有什么不同吗?

我确信必须有性能差异。但是,我想知道算法和系统规范之间的真正关系......

11 个答案:

答案 0 :(得分:6)

硬件性能的提高将为您提供算法运行时间的恒定C倍。这意味着如果您的计算机A总体上比计算机B慢2倍。那么您的算法在计算机B上的速度将是原来的两倍。但是当您考虑算法的大输入值时,两倍的速度确实几乎没有差别。

In big O notation也就是说,与C O(n)= O(c n)= O(n)相比,你会得到像O(n)这样的东西。在计算机A和计算机B上,算法的复杂性和大值的一般运行时间大致相同。

如果使用大O表示法分析算法的运行时间,那么您将更好地了解算法的实际运行方式。当您将O(logn)算法与O(n ^ 2)进行比较时,计算机性能不会给您带来任何好处。

看一下n:

的一些数据值

对于慢速计算机,我将假设每次操作1秒,对于快速计算机,我将假设2次操作。我将比较好的算法和慢速计算机与较差的算法与快速计算机进行比较。

,n = 10:

  

算法1:O(logn):4次操作   慢电脑:4秒

     

算法2:O(n ^ 2):100次操作   快速电脑:50秒

,n = 100:

  

算法1:O(logn):7次操作   慢电脑:7秒

     

算法2:O(n ^ 2):10,000   操作快速计算机:1.4小时

差异很大

,n = 1,000:

  

算法1:O(logn):10次操作   慢电脑:10秒

     

算法2:O(n ^ 2):1,000,000   操作快速计算机:5.8天

巨大的差异


随着n的增加,差异变得越来越大。

现在,如果您尝试在较快/较慢的计算机上运行这些算法,以获得较大的输入大小。没关系。放下O(logn)会更快。

答案 1 :(得分:4)

我不喜欢Brian Bondy和Czimi提供的答案......

也许这是因为我开始的是一个不同的时代,32K被认为是大量的内存,大多数“个人电脑”都有8K字节,而现在我在科学计算中工作,其中最大的数据集被处理拥有数千个处理节点和看似令人难以置信的存储量的世界上最大的系统。因此,我不会忽视问题的某些其他要素。

相关数据集的大小有很大的不同。到目前为止,大多数关于这个问题的所有答案都忽略了这一点,并为非常小的数字N工作。其他已经回答的人都认为“这一切都适合记忆”,或者接近那个。

对于大型数据集,其他因素起作用,“大”取决于您在解决问题时必须使用的资源。现代系统有机会进行离线存储(例如DVD),网络存储(例如nfs),在线存储(例如串行ATA),以及两级存储器,系统主存储器和片上高速缓存。这些是如何利用的,数据集越大,它们就越重要。您可能需要也可能不需要将这些访问设计到您的“算法”中,但如果您这样做,真的很重要!

随着您的规模超出某个特定点 - 单个CPU及其本地内存的限制是正确的 - 这些其他因素成为工作负载开销中越来越大的因素。当我是Digital时,我们在多CPU系统上做了一些真正的商业工作,我记得运行一个基准测试,显示使用单CPU作为CPU工作负载能力的一个“单位”,第二个CPU(在紧耦合系统)总共会给你1.8左右。也就是说,第二个CPU增加了大约0.8。对于三个,增加下降到大约0.6,并且四个下降了更多,大约0.2,对于四个CPU安排的总计大约2.6,尽管由于其他影响我们有一些麻烦与四个CPU保持良好的数字(测量工作成为额外资源的很大一部分)。 ...最重要的是,多CPU并不一定是它们被破解的全部 - 四倍的CPU不会给你四倍的处理能力,即使理论上你得到四倍的触发器。 ......我们重复了Alpha芯片的工作,这是历史上第一个多核心,结果非常好。当然可能已经进行了优化以提高每个额外的CPU所提供的分数,并且从那以后确实已经有很多工作可以更聪明地分割计算线程,但是你永远不会把它全部转化为每个新的100% ,部分是因为它们都会减慢一些(额外的开销)来协调。

小的感叹词 - 我们对这项工作有一个说法:“把所有重要的东西都重新编写给编译器!” RISC,明白吗?这是因为编译器本身必须组织工作负载,因此竞争线程不会相互踩踏!

最终执行真正大规模数据处理的处理需要一种非常智能的策略,即将数据移入和移出更远的数据存储到本地内存。而且,算法中的分工绝对至关重要。在我与加州大学洛杉矶分校的Roberto Mechoso一起做全球流通模型的工作中,他们有一个数据代理设计,说明人们为完成一项优秀工作所做的尝试。坦率地说,结果并不像它本来的那样好,但是进入它的设计思想值得研究。 ......假设你考虑了这个“算法”的这一部分 - 而不仅仅是一个小小的部分,那么资源的算法管理是合理的,如果不是最优的资源利用进行大量计算的最重要方面之一。

...我希望这有助于回答您的询问。

答案 2 :(得分:3)

到目前为止还没有提到的一件事是,算法通常用速度来描述,例如: O(n),O(n log(n))等......但它们在资源使用方面也有特征,其中改进的速度,比如O(n)对O(n log(n)),是内存使用量大得多的成本。在现代计算机中,当资源耗尽时,它们通常被较大的较慢资源替换,例如,交换磁盘的内存,其中较慢的资源速度要慢几个数量级。因此,当我们根据时间绘制算法的性能,并期望直线,n log n曲线等...我们经常会看到n值较大的尖峰,因为内存被挖出。在这种情况下,1GB和2GB RAM之间的差异可能很大,所以实际上,你的问题的答案是肯定的,系统规范非常重要选择算法需要了解系统规范和输入数据的大小

例如,我开发了表面建模和分析软件,我知道我的程序在32位XP盒上运行良好,适用于400万点的TIN模型。 350万到400万点之间的性能差异很小。在450万点时,性能下降非常严重,软件无法使用。

答案 3 :(得分:1)

是的,它确实取决于系统规格。一个系统可能比另一个系统快10倍,因此它将在一组数据上运行bubblesort和quicksort,速度比另一个快10倍。

但是当你对算法进行分析时,你经常忽略这样的常数因素,这是大O符号所做的一件事。所以bubblesort是O(n ^ 2),而快速排序是O(nlogn)(在一般情况下),无论你的硬件有多快,它都能保持。

有趣的是,当你开始比较苹果和橘子时。如果您在快速硬件上运行bubblesort,您可能会发现它比快速硬件上的快速排序更快 - 但只能达到一定程度。最终,使用足够大的输入设置,慢速硬件上的快速排序将比快速硬件上的bubblesort快。

如果你想开始进行这样的比较,你需要一起做两件事:确定包括常数因子在内的算法复杂度,并开发速度模型(例如,每秒可以执行的特定循环的迭代次数)你正在运行的实际硬件。与其他关于算法的书相比,Knuth Art of Computer Programming的一个有趣的事情是,他同时做了两个,所以对于他检查的每个算法,他计算了给定大小的算法需要多少单位的执行时间。在他的(神话)MIX计算机上输入。然后,您可以针对更快或更慢的硬件调整计算 - 这是大O符号无法帮助的。

答案 4 :(得分:0)

算法的效率不依赖于系统规范。效率由Ordo数字描述,它给出了处理工作量和输入大小的关系。

答案 5 :(得分:0)

当然可以。使用高CPU时,执行时间将减少。
同样的内存越高,交换数据所需的时间(如果适用)肯定会减少。

答案 6 :(得分:0)

根据您的问题,您的意思是问为什么仅根据输入大小来描述算法的效率?

算法通常使用Big O Notation来描述。该符号描述了算法的渐近行为;它描述了输入数据非常大时的行为。

例如,我们有两种排序算法。

  1. Algo#1 with O(n)
  2. Algo#2与O(n ^ 2)
  3. 让我们带两台电脑:

    1. PC1
    2. PC2比PC1快100倍
    3. 我们有两个设置:

      1. PC1运行Algo#1
      2. PC2运行Algo#2
      3. 当n非常大(如数十亿?)时,PC1仍会击败PC1:)

答案 7 :(得分:0)

请注意实施算法的语言的特殊性。

例如,在java世界中,如this article所示,速度更快的计算机并不总是意味着更快的运行时间:

  

单CPU机器上的相同Java程序实际上可以比在多进程/多核机器上运行快得多!!

答案 8 :(得分:0)

  

在Core 2 Duo 2.6 GHZ,4 GB RAM计算机或P-2,256 MB RAM计算机中运行不同的排序算法会有什么不同吗?

在某些情况下绝对!如果您的数据集不适合内存,则需要使用基于磁盘的排序算法,例如合并排序。引自Wikipedia

  

当要排序的数组的大小接近或超过可用主内存时,必须使用(慢得多)磁盘或交换空间,排序算法的内存使用模式变得很重要,并且可能是一种算法当阵列很容易适应RAM时可能会变得非常有效。在这种情况下,比较的总数变得(相对)不那么重要,并且必须从磁盘复制或交换存储器部分的次数可以支配算法的性能特征。因此,通过次数和比较的定位可能比原始的比较更重要,因为附近元素彼此的比较发生在系统总线速度(或者,缓存,甚至是CPU速度),这比较到磁盘速度,几乎是瞬间的。

     

例如,流行的递归快速排序算法提供了相当合理的性能和足够的RAM,但是由于它复制部分数据的递归方式,当数组不适合RAM时变得不太实用,因为它可能导致磁盘上的许多慢速复制或移动操作。在那种情况下,即使需要更多的总比较,另一种算法也可能更为可取。

答案 9 :(得分:0)

是。请记住,自80年代初以来,我们已经跳了大约4个数量级。 (1 MHz,10 MHz,100 MHz,1000 MHz)。 但就数据集大小而言,这只是n = 10和n = 10000之间的差异。我可以购买一个太字节硬盘......超过6?7?比我的旧20兆驱动器的数量级。

除了计算能力之外,还有更多的数据浮动。因此,虽然你可能会对big-O在n = 50时的有用程度感到困惑,但是n = 500种大小......当n = 1,000,00时你想尽可能地减少n。任何超线性对你的计算能力都是粗糙的......非多项式甚至更糟。这从系统顶部一直延伸到底部。因此,只要您处理实际数据集大小,效率就是王道。

让我举个例子。

我做了初级数据库设计。到最后我可能有5个表,其中可能有20-40个预定义的类别。添加了行,10行,20行。没什么大不了。我是个高手。我是用PHP而不是Perl做的。我是所有这一切和一个筹码

几年后搬到现在。我正在做一个关于股票市场数据的业余爱好项目。我每天从金融网站上收集数据--6100只股票,每只股票大约有10列。每周三万+行。我的初始设计是“标准化的”,静态数据和动态数据在不同的表中。当我玩我的查询,了解事情时,如果我做了一个糟糕的连接,我真的会崩溃我的服务器并让它不可用。所以我反规范化了。我的下一阶段是标记并开始实际挖掘。我不打算在圣诞节前做出严肃的预测;大约11x30K = 330K行进行挖掘和分析。如果我想及时处理我的数据,算法效率将重要。如果我的CPU速度快10倍并不重要......如果我使用N ^ 2算法,它只能以2倍的速度完成。 : - )

答案 10 :(得分:0)

  

但是,我想知道什么是真实的   算法与算法的关系   系统规格......

我很困惑。我看到很多人在这里写了很多东西,然而,当我把上面的引用作为一个问题阅读时,我就可以说:

  • 更好的系统(=更快的CPU,更多的RAM)运行得更快,更糟糕的一个(=更慢的CPU,更少的RAM)运行得更慢。相同的算法(不管它有多好或多坏)最有可能在更好的系统上运行得更快,而在更差的系统上运行得更慢。

  • 更快的算法比慢速算法运行得更快。它将在较慢的系统上运行得更快,并且在更快的系统上运行得更快。

那么你的问题到底又是什么?你的问题是“如果系统速度已经很快,我们真的需要一个快速的算法吗?慢速的那个也不行吗?”也许吧。但在这种情况下,我会问两个问题:

  1. 为什么选择慢速算法只是因为系统速度快?这样你的代码只能在速度非常快的系统上运行。如果您选择快速算法,您的代码甚至可能会在更糟糕的系统上以相当快的速度运行。

  2. 为什么要故意让性能更差?即使一个糟糕的算法可能在五秒内运行,你认为在快速机器上足够快,一个好的算法可能在100毫秒内运行。那么为什么让你的程序在5秒内完成一项任务呢?它可以在100毫秒内完成相同的任务呢?

  3. 实际上它的点数(2)确实经常让我烦恼。所以人们经常说“嘿,不要过度优化,这不重要。这个代码只是这么大系统中的一个小系统”。是的,如果你只看这个孤立的代码,那是真的。但有一种说法是“许多人都会捣蛋”。当然,您应该首先优化大多数处理器密集型部件。但是,如果一个系统由100个模块组成,并且每个模块仅占CPU时间的百分之一,那么将其中一个优化为两倍的速度只会使整体处理时间提高0.5%,几乎为零;这就是大多数人不这样做的原因。但人们忽略的是,将所有这些优化为两倍的速度将使处理时间提高50%(或者IOW,应用程序的运行速度将是整体的两倍)。

    因此,除非有充分理由不这样做,为什么不总是使用已知的最佳算法来解决问题呢?最好的方法是表现出良好的性能和良好的CPU时间/内存使用率(因为如果这个需要比普通客户PC甚至需要更多的内存,那么采用最快的那个是没用的。)