为什么运行时差异?

时间:2015-01-04 09:37:25

标签: java

我在leetcode调用Plus One上尝试了这个问题。

  

给定一个非负数表示为数字数组,加上一个数字。存储数字使得最高有效数字位于列表的开头。

我的一个解决方案的运行时间为380毫秒。我硬编码了一些值,运行时间增加到了412ms。任何人都能解释导致这种变化的原因我认为运行时间会减少,因为不会计算值。

以下是运行时间为380ms的代码:

public int[] plusOne(int[] digits) {
    int len = digits.length;

    digits[len - 1] += 1;


    if(digits[len - 1] < 10) {
        return digits;
    }
    else {
        //for(int i = len - 1; i >= 0; i--)
        int i = len - 1;
        while(digits[i] > 9) {

            if(i == 0) {
                int[] ans = new int[digits.length + 1];
                ans[0] = digits[0] / 10;
                ans[1] = digits[0] % 10;
                for(int n = 1; n < len; n++) {
                    ans[n + 1] = digits[n];
                }
                return ans;
            }
            else {
                int last = digits[i];
                digits[i] = last % 10;
                digits[i - 1] += last / 10;
                i--;

            }

        }
        return digits;
    }
}

这个花了412毫秒:

public int[] plusOne(int[] digits) {
    int len = digits.length;

    digits[len - 1] += 1;


    if(digits[len - 1] < 10) {
        return digits;
    }
    else {
        //for(int i = len - 1; i >= 0; i--)
        int i = len - 1;
        while(digits[i] > 9) {

            if(i == 0) {
                int[] ans = new int[digits.length + 1];
                ans[0] = 1;
                ans[1] = 0;
                for(int n = 1; n < len; n++) {
                    ans[n + 1] = digits[n];
                }
                return ans;
            }
            else {
                int last = digits[i];
                digits[i] = 0;
                digits[i - 1] += 1;
                i--;

            }

        }
        return digits;
    }
}

4 个答案:

答案 0 :(得分:0)

程序的运行时间取决于各种因素,通常会有所不同。过于简化的答案是您的计算机处理器必须在所有正在运行的进程之间安排时间,这将影响程序的运行时间。

如果您在没有运行其他程序的计算机上运行此程序并运行此测试许多次,那么您可以查看运行时间是否存在真正差异的平均值。

答案 1 :(得分:0)

使用380毫秒的程序:

您指定数字和ans数组硬编码,这是更快更糟糕的方式(代码可读性更低)

如:

digits[i] = 0;
ans[0] = 1;
ans[1] = 0;

412毫秒的程序: 您为数组分配了操作或变量调用,这需要更多时间。(这使代码具有更高的可读性)

如:

digits[i] = last % 10;
ans[0] = digits[0] / 10;
ans[1] = digits[0] % 10;

时差来自于此。

还有许多可能的原因导致代码中的时间差异与编码知识和技术有关

答案 2 :(得分:0)

这实际上取决于您的计算机的状况。流程运行得更快有时。您需要多次测试该程序。此外,它以毫秒(毫秒)计算。 ms是1/1000秒。如果它有很少 ms的差异,那真的不重要。除法是一个非常简单的计算(对于计算机)。现代处理器可以在非常短的时间内完成它。你不是在使用20世纪20年代的处理器。

作为结论,你只是删除了一些分歧,这意味着你不会有太大的延迟。不要介意微小的延迟;)当您运行第二个代码时,IDE可能正在编译其他项目。

答案 3 :(得分:0)

可能影响时间结果的一些主要因素是:

  • JVM热身
  • 垃圾收集器
  • 您没有看到(重新排序等)的编译器优化 - 对于您的案例ans[0] = digits[0] / 10; ans[1] = digits[0] % 10;等可能已经优化到固定值,因为这些值永远不会改变。< / LI>
  • 使用资源的操作系统/机器的其他正在运行的进程

你应该在进行真正的计算之前预热JVM,怎么做?在实际测量之前进行一些测试测量(确保预热需要几秒钟才能完成)。我个人从未决定何时基准时间不到1秒,而我正试图创建一个更大的问题来查看实际结果。

如果每次运行的时间太短(某些ns或ms),则必须增加问题的大小,例如在您的情况下,增加表的大小,直到您获得几秒钟的时间测量(例如尝试使用数百万个元素)。

要使用较小的表格大小进行测试,您始终必须创建一个循环来测量问题的多次运行,然后将总时间与这些循环重复次数分开。例如,

 //after the warm up try the following
 int repetitions = 1000;
 start = System.nanoTime();
 for (int i=0; i<repetitions; i++) {
     //your calculations
 }
 end = System.nanoTime();
 System.out.println("Cost per repetition: " + (end - start)/repetitions);

还有一些工具,请参阅Caliper项目