1

我创建了一个新的冒泡排序项目,我想知道它需要多少时间。因此,我添加了一个getTime()返回 nanotime 的方法。我还创建了一个包含 9 个静态值的数组。当我运行我的代码时,我得到不同的运行时间(即:通常我得到 3849 ns,但有时是 6432 或 4277 ns)。怎么会这样?

我的代码如下:

long time2;
public void sort(int[] dizi){
    long time = System.nanoTime();
    for (int i = dizi.length-1; i >0; i--) {
        for (int j = 0; j < i; j++) {
            if(dizi[j]>dizi[j+1]){
                super.swap(dizi, j, j+1);
            }
        }
    }
    time2 = System.nanoTime() - time;
}
public long getTime(long time){
      return time;
}
main(){
      BubbleSort bubbleSort = new BubbleSort();
      int[] arr = {4,2,1,8,9,5,3,7,6};
      bubbleSort.sort(arr);
      Sysout(bubbleSort.getTime(time2));
}
4

2 回答 2

0

有多种因素可能会影响结果。

JVM 可能会开始运行垃圾收集(这绝对不是您的情况),而运行您的程序 JVM 可能会分配一些内存,并且底层操作系统服务发现它应该交换一些内存,因为它已经用完了可用的 RAM,等等......

没有可用的 JVM(适用于 Mac、Windows 和 Linux/Unix)在实时系统上运行,但即使有一天它会运行 - 您的 JVM 可能会决定您的程序与某些 JVM 活动相比具有较低的优先级。

尝试一些更大的数组,结果会更稳定。

于 2013-03-18T00:46:13.290 回答
0

除非您运行的硬件可以准确地测量纳秒(提示 - 它不能),否则 Java 无法为您提供以 ns 为单位的准确时间戳。

最重要的是,Java 在代码的运行时间方面不是确定性的。在任何时候,您的代码都可能被 JVM 正在运行的大量其他内务处理任务打断,尤其是垃圾收集。

还有一个 Hot Spot 编译器,它将识别一段经常运行的字节代码,并将其重新编译为本机代码,这会导致暂停,但随后运行时性能会有所提高。如果你想从方程中去除热点效应,你需要通过运行代码几万次来浸泡测试你的代码,以确保它已被编译为本机代码,然后执行实际的定时运行以查看代码的效率如何。

如您所见,最终结果是代码可以运行多次,产生相同的结果,但返回该结果需要不同的时间,而对于各地的强迫症编码员来说,坏消息是您永远不会使数字相同每次测试运行。

对于这样的性能测试,我通常希望运行代码可能 1000 次,并在我的时间记录上记录最快时间、最慢时间、平均时间和标准偏差,以准确了解特定代码的运行时间。如果出现意外的缓慢运行,我会在 VM 上启用详细 GC 选项时在日志中查找完整的 GC 事件。

哦,别忘了运行你的 JVM 的操作系统也提供了可变数量的运行时,操作系统也有它正在运行的内务处理。

于 2013-03-18T00:34:11.433 回答