我正在尝试计算算法性能。基本上,我的算法可以解决集合操作(例如合并,分解,交集等)。我的算法可以在O(logn)中完成此操作,以与类似的算法进行比较,我实现了对解决方案blooms filter algorithm,有序列表的原始方法,但是当试图计算运行时间,我发现其他算法中的某些操作实际上需要0(零)纳秒来完成。通过操作,我的意思是找到两个集合的并集,每个集合中有10000个元素。那怎么可能?您可以在Github上看到我的项目。 我计算运行时间的部分在测试包中
我尝试使用Jprofilier来确保它们都在一个线程上运行
我尝试在时间间隔之间进行调试,以确保它不会忽略计算并找到正确的结果
static Duration IntersectDocumentsTime(AlgorithmInterface algorithm)
{
Instant start = Instant.now(); // Time before calulation i tryed to put breakpoint here
algorithm.IntersectDocuments(); // returns Term[] result of elements after union operation
Instant end = Instant.now(); // Time after calulation
return Duration.between(start,end); // i put a breakpoint here to see if IntersectDocuments() result is correct and actually calculated
}
这是我打印结果的方式
for (AlgorithmInterface al: Algorithms)
{
System.out.println("------------------------------------------------------------------------------");
System.out.println("Algorithm: "+al.getClass().toString()+"\tOperation: Union\nTime: "
+OperationsInterface.AddDocumentsTime(al).toNanos()+"\tseconds");
System.out.println("Algorithm: "+al.getClass().toString()+"\tOperation: Disjuction\nTime: "
+OperationsInterface.DisjointDocumentsTime(al).toNanos()+"\tseconds");
System.out.println("Algorithm: "+al.getClass().toString()+"\tOperation: Intersection\nTime: "
+OperationsInterface.IntersectDocumentsTime(al).toNanos()+"\tseconds");
System.out.println("Algorithm: "+al.getClass().toString()+"\tOperation: Subtraction\nTime: "
+OperationsInterface.SubtractDocumentsTime(al).toNanos()+"\tseconds");
System.out.println("Algorithm: "+al.getClass().toString()+"\tOperation: Find\nTime: "
+OperationsInterface.ContainsTermTime(al,new Term("A")).toNanos()+"\tseconds");
}
System.out.println("------------------------------------------------------------------------------");
结果看起来像这样
算法:类Algorithms.FNA.FNA操作:联合 时间:1851133600秒 算法:类Algorithms.FNA.FNA操作:伪装 时间:1799607700秒 算法:类Algorithms.FNA.FNA操作:交叉点 时间:291703600秒 算法:类Algorithms.FNA.FNA操作:减法 时间:1022775100秒 算法:类Algorithms.FNA.FNA操作:查找 时间:1319100秒
算法:类Algorithms.Primitive.Primitive操作:并集 时间:81257800秒 算法:类Algorithms.Primitive.Primitive操作:Disjuction 时间:85717600秒 算法:类Algorithms.Primitive.Primitive运算:交集 时间:0秒 算法:类Algorithms.Primitive.Primitive运算:减法 时间:66472900秒 算法:类Algorithms.Primitive.Primitive操作:查找 时间:0秒
算法:类Algorithms.BloomsFilter.BloomsFilter操作:联合 时间:998900秒 算法:类Algorithms.BloomsFilter.BloomsFilter操作:伪装 时间:0秒 Algorithm:类Algorithms.BloomsFilter.BloomsFilter操作:交集 时间:503800秒 Algorithm:类Algorithms.BloomsFilter.BloomsFilter操作:减法 时间:0秒 Algorithm:类Algorithms.BloomsFilter.BloomsFilter操作:查找 时间:1312900秒
算法:类Algorithms.SortedList.SortedList操作:联合 时间:0秒 算法:类Algorithms.SortedList.SortedList操作:伪装 时间:3721800秒 算法:类Algorithms.SortedList.SortedList操作:交集 时间:0秒 算法:类Algorithms.SortedList.SortedList操作:减法 时间:810500秒 算法:类Algorithms.SortedList.SortedList操作:查找 时间:1173200秒
答案 0 :(得分:4)
不要自己编写微观基准,请使用JMH框架。这将确保您避免常见的陷阱,例如分层编译。
在您的代码中:
Instant start = Instant.now();
algorithm.IntersectDocuments();
Instant end = Instant.now();
return Duration.between(start,end);
algorithm.IntersectDocuments()
如果没有副作用,可以进行优化。
请注意,Instant.now()
在not suitable for calculating elapsed time的幕后使用System.currentTimeMillis()
。
答案 1 :(得分:2)
Instant.now()
将使用当前时间(以毫秒为单位)。深入查看代码,您可以看到它使用System.currentTimeMillis()
。
除了使用上面的方法,您还可以使用以下代码,其中我使用的时间以纳秒为单位。
static long IntersectDocumentsTime(AlgorithmInterface algorithm) {
long start = System.nanoTime();
algorithm.IntersectDocuments();
long end = System.nanoTime();
long durationInNanos = end - start;
return durationInNanos;
}