0

我和我的朋友做了一个程序来做同样的事情,他的在 java 中,我的在 python 中。我们必须解决的问题是“能被 1 到 20 的所有数字整除的最小正数是多少?” 我们都得到了正确的答案,据我所知,实现起来非常相似,但他的答案在大约三秒钟内完成,而我的则花了一分钟。谁能明白为什么会这样?为了清楚起见,我知道这两种方式都不是最好的,但它们都有效,我感兴趣的是看看为什么会有如此显着的时差。谢谢!

爪哇:

for (int i = 1; i > 0; i++) {
    for (int j = 1; j < 21; j++) { 
        if (i % j != 0) {                  
            break;
        }
        if (j == 20) {
            System.out.println("ANSWER: " + i);
            System.exit(0);
        }
    }
}

Python:

e=1
while e > 0 :
    num =1
    while num < 21:

        if e % num != 0:
            break
        num += 1



    if num == 21:
        print e
        break
    e += 1
4

2 回答 2

6

虽然您在 python 中的实现看起来很相似,但缩进非常重要。在 Java 版本中,此块:

if(j == 20){
    System.out.println("ANSWER: " + i);
    System.exit(0);
}

在第二个 for 循环内。在 python 版本中,块:

if num == 21:
    print e
    break

在第二个 while 循环之外。

于 2013-07-16T14:51:29.997 回答
3

大多数 Java 实现会将字节码编译为机器码;即使不是这样,Java 的字节码也与基本的机器操作相对接近。另外,当然,intJava中的an是一种基本的机器类型;在 Python 中,它是一个类类型,完全支持溢出检测并在必要时转换为 long int,并通过函数调用进行加法,并且该函数在该类型的映射中查找。

编辑:

为了更清楚地说明我在说什么,请考虑以i += 1Python++ i和 Java 的形式声明。在没有 JIT 编译器的情况下,Java 中的字节码将按照以下方式恢复:

push i
push 1
add
pop i

字节码可能由一个大开关执行:上面的每个字节码指令最多会占用两到三个机器指令。的地址i将被编译成字节码,而变量本身将相当于int32_tC中的 an。

在 Python 中,等效的伪代码类似于以下内容:

look up i in the module's dictionary.
look up __add__ in the resulting object's dictionary.
call the i.__iadd__( int(1) )

并且i.__iadd__不仅会添加值,还会检查溢出并在必要时将类型转换为 long。

简而言之,在最坏的情况下(因为使用 JIT 编译器,用于此的 Java 代码将导致英特尔处理器上的单个机器指令),我们谈论的是 10-20 条 Java 机器指令。Python 的机器指令数量很容易达到数千。

于 2013-07-16T14:55:42.373 回答