当前位置: 首页 > 知识库问答 >
问题:

Java算法时间度量

谭泉
2023-03-14

我的问题是,当我试图获得算法执行时间的准确测量值时,一旦第一组测试完成,结果就会相差很大。

我有7个带整数的文本文件,每个文本文件有两个元素的幂。

24=16
28=256
212=4096
216=65536
220=1048576
222=4194304
224=16777216

我运行这些测试X次以获得执行时间。一个测试用例被认为执行了上述所有测试一次。我在不改变文本文件数据的情况下做了几次。

为了测量我的算法执行时间,我使用系统。纳米时间();

        long start = System.nanoTime();
        (Algorithm)
        long elapsedNanoTime = System.nanoTime() - start;

然而,结果显示,在执行第一个测试用例之后,开始测试16和256的测试数量大幅下降。

测试用例,迭代1:

16个元素取325336n
256个元素取414861n
4096个元素取2061728n
65536个元素取21111426n
1048576个元素取326898979n
4194304个元素取1487154649n
16777216个元素取6700800203n

测试用例,迭代2:

16个元素需要2925n
256个元素需要36864n
4096个元素需要885603n
65536个元素需要15839933n
1048576个元素需要332000198n
4194304个元素需要1484967410n
16777216个元素需要6695675287n

测试用例,迭代3:

16个元素需要2926n
256个元素需要35985n
4096个元素需要679635n
65536个元素需要15462227n
1048576个元素需要328179551n
4194304个元素需要1483733064n
16777216个元素需要6704160641n

如果我单独运行每个测试用例,“编译”程序,只做7个测试,结果都与上面的迭代1类似。

那么,对于为什么执行时间不同于第一个测试用例和其他测试用例,有人有什么见解吗?它是否与程序的初始化有关,或者内存已经在某个地方分配了数据?因为到目前为止,我不确定哪个执行时间数据是正确的。

提前感谢。

共有2个答案

金高轩
2023-03-14

考虑使用jmh作为微基准测试的框架。正如@dimo414的答案所指出的,JVM很难进行基准测试。

金亦
2023-03-14

基准测试很难,你偶然发现了一个更常见的麻烦案例;JIT编译器。JVM实际上负责编译在运行时运行的一些代码,以便进一步优化字节码,而不是编译器本身所能做到的。

描述如何确保基准测试是准确的超出了答案的范围(但有很多资源),但对于这个特定问题,您想要做的是多次运行基准测试(在同一个JVM中),并将前几次运行作为噪声丢弃。一旦基准测试运行了几次,JIT将有机会为您优化代码,并且可能不会在后续运行中进行更多优化。

 类似资料:
  • 算法的时间与空间复杂度 看到群里们小伙伴在讨论算法复杂度问题,之前在极客时间看了王争的《数据结构与算法之美》,看的我也晕呼呼的,跟上学时在学校老师的讲的有点不一样了,网上搜了下各种各样的,结合参考作一篇简单易懂的总结。 什么是算法 算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。 如何评价一个算法的好坏 一般我们会从以下维度来评估算法的优劣 正确性

  • 我已经通过谷歌和堆栈溢出搜索,但我没有找到一个关于如何计算时间复杂度的清晰而直接的解释。 说代码像下面这样简单: 说一个像下面这样的循环: 这将只执行一次。 时间实际上被计算为而不是声明。

  • 本文向大家介绍k-means算法的时间空间复杂度?相关面试题,主要包含被问及k-means算法的时间空间复杂度?时的应答技巧和注意事项,需要的朋友参考一下 时间复杂度为O(tmnK) t表示迭代次数,m表示数据个数,表示数据特征维度,K表示类簇数 空间复杂度为O((m+K)*n) m表示数据个数,K表示类簇个数,n表示维度,理解就是需要存储数据点和类中心点

  • 下面是我写的一些伪代码,给定一个数组A和一个整数值k,如果与k之和中有两个不同的整数,则返回true,否则返回false。我正试图确定这个算法的时间复杂度。 我猜这个算法在最坏的情况下的复杂度是O(n^2)。这是因为第一个for循环运行n次,该循环内的for循环也运行n次。if语句进行一次比较,如果为true,则返回一个值,这两个操作都是常量时间操作。最后的return语句也是一个常数时间操作。

  • 每个顶点可以连接到(V-1)个顶点,因此每个顶点的相邻边数是V-1。假设E代表连接到每个顶点的V-1条边。 查找和更新最小堆中每个相邻顶点的权重为O(log(V))+O(1)或 因此,从上面的步骤1和步骤2,更新顶点的所有相邻顶点的时间复杂度是e*(logV)。或. 因此所有V顶点的时间复杂度为V*(E*logv),即。 但Dijkstra算法的时间复杂度为O(ElogV)。为什么?

  • 我正在使用来调度多个java作业。我想知道在以下情况下会发生什么: 如果我在使用, 运行命令,长首字母延迟,长周期,时间单位 用于调度5个线程池大小为1的作业 p1-5(以分钟为单位的执行间隔) p2-5 p3-5 p4-7 p5-10 5分钟后,p1、p2和p3将激活争用。 将作业分配给一个可用线程使用什么算法?他们会以循环方式分配吗? 现在在第7分钟,假设p1和p2完成,p4变为活动状态,但p