2015-10-17 43 views
1

所以我一直在看人們編寫代碼,當他們希望看到給定值的平方版本時,他們會寫出x * x而不是x ** 2 。在這兩點之間是否存在效率重疊的問題,python中的給定函數不僅僅是被使用,還是僅僅是一個風格點?我更願意使用**操作符,但如果它會導致巨大的失誤,我應該做這個操作十億次,我知道的過度我想知道。另外,如果我在一個接管另一個的操作的數量級上錯誤的話,我還想糾正這個問題。即如果**比x * x更有效,那麼我想知道爲什麼。*與**爲2操作的功率

+1

我想人們使用'x * x'而不是'x ** 2',因爲它適用於所有語言,而'x ** 2'不適用於Java/C/C++。所以我想大多數例子的原因是無知的。不過,我很想知道是否存在效率差異/數字差異。 –

回答

3

我不同意g.d.d.c,乘法速度要快得多!

"""Evaluating the difference in execution time between n*n and n**2""" 

from time import time 

n = 2 
t = time() 
for i in range(5000000): 
    n**2 
print("Time for n**2:\t%0.3f" % (time()-t)) 
t = time() 
for i in range(5000000): 
    n*n 
print("Time for n*n:\t%0.3f" % (time()-t)) 


def test(n): 
    """ 
    Difference in execution time between n*n and n**2 
    within function scope. 
    """ 
    t = time() 
    for i in range(5000000): 
     n**2 
    print("Time for n**2:\t%0.3f" % (time()-t)) 
    t = time() 
    for i in range(5000000): 
     n*n 
    print("Time for n*n:\t%0.3f" % (time()-t)) 

test(n) 

結果:

Time for n**2: 2.324496030807495 
Time for n*n: 0.5879969596862793 
Time for n**2: 2.0771241188049316 
Time for n*n: 0.2894318103790283 

你可以看到,乘法是更快的功能以外的4倍左右,而在功能快7倍。我無法解釋這兩個測試之間的區別,我不確定n * n和n ** 2之間的區別,但它可能與Python是一種解釋型語言以及後者的處理過程有關更多的時間,即使處理器操作非常相似,如gddc所示。

+1

爲什麼它在功能上或功能之外有所作爲(如此龐大!)? –

+1

@moose:很可能是因爲全局變量查找是字典查找,而局部變量查找是索引到數組中的。 – user2357112

+1

現在我有點困惑了,我看到它確實考慮到了巨大的速度差異,這表示我的初始點。我並不認爲這會有很大的差別,或者它會導致在功能範圍內或在功能範圍外的區別。有時這種奇怪的語言。 –

2

實際上,兩者很可能在總成本很相似:

>>> def s1(x): 
... return x * x 
... 
>>> 
>>> def s2(x): 
... return x ** 2 
... 
>>> 
>>> from dis import dis 
>>> 
>>> dis(s1) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_FAST    0 (x) 
       6 BINARY_MULTIPLY 
       7 RETURN_VALUE 
>>> dis(s2) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    1 (2) 
       6 BINARY_POWER 
       7 RETURN_VALUE 
>>> 

我想你可能過早地優化,即使是百萬或數十億的迭代。除非你認爲這是一個瓶頸,只要使用你最習慣的東西。

而且,爲了完整起見,timeit結果:

>>> timeit.Timer("s1(10)", 'from __main__ import s1').timeit(100000) 
0.0186597650628606 
>>> timeit.Timer("s2(10)", 'from __main__ import s2').timeit(100000) 
0.018789616358585448 

這似乎表明x * x非常輕微更快100000迭代。

+0

所以它本身就是一種風格概念。我一直認爲它只是沿着c中的pow()函數的行,因爲它做了一個函數調用,我看到了該語言的需要,但是在python中,因爲它是內置的。我只是不明白爲什麼不使用它。在我看來,與其他人相比,我的觀點更具表現力,只要運營商是知名的和理解的。不過謝謝你的提示。 –

+0

對於10e6來說,這是價值,但它會在時間複雜度上呈指數級增長還是持續增長?我知道在宏大的計劃中,這隻會少一點,但要做歐拉問題,自學Python語言,甚至時間,甚至是四分之一秒,都會讓我有點困惑。 –

+2

Nah。指數運算比常規CPU上的乘法運算慢得多。你的基準沒有顯示出來,因爲時間是由函數調用(我猜)或其他動態Python shenanig的成本占主導地位。在編譯語言中,差異是巨大的。即使在Python中,我也可以想象它在沒有函數調用的緊密循環中產生巨大差異,但我沒有進行基準測試。無論如何,這(很不幸)遠不是許多應用程序的過早優化。 –