为什么相同算法的运行时差异如此之大?

时间:2012-09-22 08:35:56

标签: java python performance

我做了采访街道问题string similarity。最初我在python中做了这个。这给了我最后5个测试用例的Time Limit Exceeded错误。然后我在java中尝试了相同的一个,解决方案被接受了。最后5个测试用例的java和python版本之间的时差非常高,但前5个测试用例的python beats java。为什么会这样?

字符串的长度可以达到100000。

stringsim.py

N=int(raw_input())
while N!=0:
    rootstr=[i for i in raw_input()]
    solution=0
    for i in xrange(len(rootstr)):
        for j in xrange(i,len(rootstr)):
            if(rootstr[j-i]==rootstr[j]):solution+=1
            else:break
    print solution
    N-=1

Solution.java:

class Solution{
    public static void main(String[] args) {
    java.util.Scanner sc=new java.util.Scanner(System.in);
    int N=sc.nextInt(),sol;
    while(N--!=0){
        sol=0;
        char[] s=sc.next().toCharArray();
        for(int i=0;i<s.length;i++){
            for(int j=i;j<s.length;j++){
                if(s[j]==s[j-i]) sol++;
                else break;
            }
        }
        System.out.println(sol);
    }
    }
}
Run time for java:
1               Success 0.172387
2       Success 0.172177
3       Success 0.172185
4       Success 0.172178
5       Success 0.263904
6       Success 2.82661
7       Success 4.66869
8       Success 4.83201
9       Success 1.36585
10      Success 1.02123

For python:
1       Success                 0.081229
2       Success             0.081047
3       Success             0.081032
4       Success             0.081015
5       Success                 0.910672
6       Time limit exceeded.    16.1818
7       Time limit exceeded.    16.2357
8       Time limit exceeded.    16.2001
9       Time limit exceeded.    16.2408
10      Time limit exceeded.    16.1831

2 个答案:

答案 0 :(得分:1)

我同意iccthedral的评论:Java JIT可能是Python为前几个小输入更快的原因。要验证这一点,请反转输入顺序(以便首先输入大输入),对同一过程中的所有输入运行它,并再次测量每个输入的时间。如果Python在最后几个(小)输入的情况下速度很慢,则可以确认推定。

验证它的另一种方法是将小输入添加到末尾(也将它们保留在开头),并查看Java执行所有内容所需的时间。如果delta仅比小输入的执行时间大得多,则确认推定。

Java JIT将Java字节码编译为机器代码(CPU可以直接且非常快速地执行)。但只转换了那些Java花费大量时间执行它们的Java方法。 (这是因为将所有方法转换为机器代码会很慢并且生成的机器代码需要太多内存。)因此,当Java进程启动时,它会开始执行所有方法作为字节码,它会测量每个方法花费的时间。方法,一旦达到方法的阈值,它就使用JIT将该方法编译为机器代码。之后,该方法执行得更快。但是,在流程执行开始时,所有方法都很慢,并且在短时间内Java进程变得更慢,因为它忙于运行JIT。

在您的情况下可能会发生这种情况:当Python找到简单问题的答案时,Java仍在运行字节码或运行JIT以将字节码编译为机器代码。但最终Java会迎头赶上,因为机器代码要快得多。

答案 1 :(得分:1)

尝试用Java来衡量自己的时间。我的意思是在main方法中计算毫秒数。在Python中做同样的事情。我想你的答案中的时间是用OS来衡量的 - java进程运行的时间。前5个示例的时间可能主要是启动JVM进程的开销。