在python中使用JIT时不可能加速。发生了什么事?

时间:2016-08-08 01:42:29

标签: python jit

我试图测试在python中使用JIT的速度提升。这是我使用的代码。

from numba import jit
import timeit

@jit # Commented out when testing pure python
def sumof():
    x = 0
    for i in xrange(1000000000):
        x += 1
    return x

def timer():
    sumof() # Run once to initialize the JIT compiler
    l = []
    t = timeit.default_timer()
    for x in range(10):
        l.append(sumof())
    return timeit.default_timer()-t, l # Returns the time elapsed and the list of results, to verify accuracy

print timer()

这给出了与此类似的结果

(5.643910299113486e-06, [1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000])

现在我知道原始CPU性能比纯python快几个数量级,但是在5微秒内有100亿次操作?我测试了相同的代码,但使用了有符号64位整数的最大值而不是仅仅十亿。这是结果。

(5.643909389618784e-06, [9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L, 9223372036854775807L])

~92千万亿次操作......在5微秒内完成。根据我的数学计算,这是一次大约16次septillion操作。有些事情显然是错误的,但却给出了正确的结果。我怀疑编译器在某种程度上摆脱了for循环,但为什么呢?我该如何预防?

1 个答案:

答案 0 :(得分:1)

优化器似乎很可能已经用一个常量计算替换了循环。有关经典循环优化的列表,请参阅this issue。在这种情况下,完全展开循环,然后组合所有常量,得到return n(x + = 1)或return n * b(x + = b)。使用x += i会产生return n * (n + 1) / 2。 (在每种情况下n都是适当的上部循环界限:在i中求range(n)时,它实际上只是n-1。)

因为这是一个JIT编译器,它甚至可以为变量n执行此操作,尽管在您的示例中每个n都是常量,因此即使非JIT编译器也可以执行此操作。