(Dis)由于语言内部原因,证明一种算法比另一种算法运行得更快

时间:2010-12-20 00:41:03

标签: java algorithm optimization complexity-theory time-complexity

对于大学的项目,当给定一组元素和所述元素之间的关系集合时,我们必须实现一些不同的算法来计算等价类。

我们被指示实施Union-Find算法及其优化(Union by Depth,Size)等。偶然(做一些我认为对于算法的正确性是必要的)我发现了另一种优化算法的方法。

它没有Union By Depth那么快,但接近。我不能为我的生活弄清楚为什么它会像现在一样快,所以我咨询了一位无法弄明白的教学助理。

该项目是在java中,我使用的数据结构基于简单的整数数组(对象,而不是int) 后来,在项目的评估中,我被告知它可能与“Java缓存”有关,但我无法在网上找到关于缓存如何影响这一点的任何内容。

在没有计算算法复杂性的情况下,最好的方法是证明或反驳我的优化是如此快,因为java的做法是什么?用另一种(低级?)语言实现它?但谁能说语言不会做同样的事情呢?

我希望自己清楚明白,

感谢

4 个答案:

答案 0 :(得分:4)

唯一的方法是证明算法的最坏情况(平均情况等)复杂性。

因为如果不这样做,可能只是

组合的结果
  • 特定数据
  • 数据的大小
  • 硬件的某些方面
  • 语言实现的某些方面

答案 1 :(得分:3)

在给定现代VM的情况下执行此类任务通常非常困难!就像你暗示他们背后的各种各样的东西。方法调用内联,对象被重用。等等。一个主要的例子是看看如果他们显然没有执行除计数以外的任何其他操作,那么如何编译琐碎的循环。或者函数式编程中的函数调用如何内联或尾调用优化。

此外,您很难在任何数据集上证明您的观点。 O(n ^ 2)可以比看似更快的O(n)算法快得多。两个例子

  1. 冒泡排序在排序近排序数据集合时比快速排序更快。
  2. 在一般情况下快速排序,当然更快。
  3. 通常,大O符号故意忽略常量,在实际情况下,这些常数对您的实现来说意味着生死。那些常数可能是什么打击了你。所以在实践中0.00001 * n ^ 2(比如算法的运行时间)快于1000000 * n log n

    鉴于您提供的信息有限,所以推理很难。

答案 2 :(得分:1)

编译器或JVM很可能找到了代码的优化。您可以尝试读取javac编译器输出的字节码,并使用-Djava.compiler=NONE选项禁用运行时JIT编译。

答案 3 :(得分:0)

如果您有权访问源代码 - 并且JDK源代码可用,我相信 - 那么您可以通过它来查找相关的实现细节。