假设我有“Heap Sort”方法,其复杂时间为O(nlogn)。当我在1000000输入上测量此方法的执行时间时,我得到了0.375770669秒。如何从理论上计算出该方法的执行时间?
答案 0 :(得分:5)
理论上没有办法计算这个。这取决于许多因素,例如:
即使您了解所有这些,计算本质上也是Java JIT编译器和硬件执行的取证模拟。考虑起来太复杂了。
您可以合理地期望在“速度”的理论度量方面实现的最佳目标是在源代码级别计算抽象操作。即使向下钻取并计算执行的字节码也可能难以实现。
我想比较测量的和理论的。
基本上,你不能。
答案 1 :(得分:2)
您可以做的是为不同数量的输入运行代码,例如1000,10000,100000,1000000,10000000等,并记录排序所花费的时间。然后根据X-Y图中的元素数绘制这些记录时间,看看是否得到O(nlogn)
复杂度曲线。
另请参阅本文档以了解堆排序分析和演示:http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/heap/heapen.htm
答案 2 :(得分:1)
请记住,O(·)或Θ(·)符号描述渐近增长率,在限制中,因为n接近无穷大:它描述了比如,算法得到你将输入大小乘以10。这与实际输入大小(与“无穷大”相比总是无限小)的实际执行时间的对应程度取决于用于分析算法的理论模型与您拥有的实际机器的对应程度。
具体来说,“堆排序取Θ(n log n)时间”意味着存在常数c 1 和c 2 ,使足够大n ,如果T(n)是大小为n的输入所用的时间,那么
c 1 n log n< T(n)< c 2 n log n
n = 1000000的大小可能会或者可能不是“足够大的n”,无法进行渐近行为。
然而,假设它是,并且将该语句解释为表示所花费的时间大致为(cn log n)某个常数c,等于
c1000000lg(1000000)= 0.375770669秒
给出c≈1.88×10 -8 。这意味着大小为n = 2000000的输入应该花费大约0.79秒,并且n = 10000000应该花费大约4.38秒。您可以将此“理论”结果与通过使用该大小的输入运行算法获得的实验结果进行比较。
对于典型的计算机来说,一个粗略的经验法则是,对于慢速计算机和算法,c介于10 -7 之间,而对于相当不错的计算机而言,c <10> sup> -9 。将两端的另外两个因子乘以两个是安全的。 (这个想法是典型的分析给出常数c,例如1-200,典型的计算机速度在一个数量级或两个数量级。当然,“典型”是主观的,如果你尝试使用Fibonacci,你会可能会感到失望。)
从先验猜测c大约10 -8 开始,假设运行时间约为0.2秒。