2016-04-15 70 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'。 –