2016-04-15 72 views
3

我读过math.sqrt**快,今天我试了一下。但有趣的是不是值这两个而是变量**之间的时间差和**之间的时间差:变量查询:为什么**的变量如此慢于值

value1 = 10.1 
value2 = 0.5 
%timeit value1 ** value2 
# 1000000 loops, best of 3: 645 ns per loop 
%timeit 10.1 ** 0.5 
# 10000000 loops, best of 3: 60.7 ns per loop 

这是快十倍以上。而对于数学函数的时机几乎是相同的(多用于变量查找只有几个纳秒):

import math 
%timeit math.sqrt(10.1) 
# 1000000 loops, best of 3: 529 ns per loop 
%timeit math.sqrt(value1) 
# 1000000 loops, best of 3: 568 ns per loop 

任何人都可以解释为什么变量查找使得这种巨大的差异为**,同时它使math.sqrt差别不大?

设置:

  • 蟒蛇3.5
  • 的Windows 10的64位

回答

4

使用变量:

In [41]: def var(): 
    ....:  value1 ** value2 
    ....:  

In [43]: dis.dis(var) 
    2   0 LOAD_GLOBAL    0 (value1) 
       3 LOAD_GLOBAL    1 (value2) 
       6 BINARY_POWER 
       7 POP_TOP 
       8 LOAD_CONST    0 (None) 
      11 RETURN_VALUE 

使用立即值:

In [44]: def imm(): 
    ....:  10.1 ** 0.5 
    ....:  

In [45]: dis.dis(imm) 
    2   0 LOAD_CONST    3 (3.1780497164141406) 
       3 POP_TOP 
       4 LOAD_CONST    0 (None) 
       7 RETURN_VALUE 

原来,编译器超过了我们,并预先计算了功耗。

+0

很好知道这样的操作是事先执行的。这真的让我感到惊讶,但它是有道理的。你碰巧知道这些计算的时间?因为通常'%timeit'会打印一条消息,如果一次运行比其他运行时间长得多,并且情况并非如此。 – MSeifert

+0

编译时间,所以'%timeit'没有警告,因为它一遍又一遍地运行相同的'LOAD_CONST'。 –