我想知道 x**2 或 x*x 是否更快
def sqr(x):
for i in range (20):
x = x**2
return x
def sqr_(x):
for i in range (20):
x = x*x
return x
當我計時時,這就是我得到的:
The time it takes for x**2: 101230500
The time it takes for x*x: 201469200
我試了很多次,要么相等,要么 x ** 2 比 x * x 快。但是 x*x 永遠不會比 x**2 快。
所以我反匯編了代碼:
對于 x**2:
5 12 LOAD_FAST 0 (x)
14 LOAD_CONST 2 (2)
16 BINARY_POWER
18 STORE_FAST 0 (x)
20 JUMP_ABSOLUTE 8
對于 x*x:
9 12 LOAD_FAST 0 (x)
14 LOAD_FAST 0 (x)
16 BINARY_MULTIPLY
18 STORE_FAST 0 (x)
20 JUMP_ABSOLUTE 8
是關于 load_const 比 load_fast 稍快嗎?
LOAD_CONST:獲取 co_consts 索引 1 處的文字值并將其推送
LOAD_FAST 正在按索引訪問陣列中的值
還是 binary_power 比 binary_multiply 快(我其實不知道 binary_power 演算法)?
uj5u.com熱心網友回復:
對于小整數,x*x比x**2CPython 在內部執行更多操作來計算要快得多a**b。實際上,在我的機器x*x上要快 4 倍(處理器 i5-9600KF,CPython 3.8.1,在 Windows 上)。話雖如此,在您的代碼中,數字增長得非常快,Python 整數是無限的。事實上,每次取冪都會導致二進制表示變大兩倍。指數相乘,得到 的計算結果x**(2*2*2*...*2) = x**(2**20) = x**1048576。對于 big x=2,該數字需要 128 KiB 的記憶體,對于x=100它需要 850 KiB。這是相當大的。回圈的每次迭代都受到記憶體中如此巨大數字的計算的限制。因此,對于大量資料,x*x并且x**2速度一樣快因為這兩種情況都進行了相同的內部計算,與計算大整數相比,CPython 解釋器的開銷可以忽略不計。
在引擎蓋下
在內部,CPython 似乎使用_PyNumber_PowerNoModwhich calls PyNumber_Powerwhich callsternary_op和PyNumber_Multiplywhich calls binary_op1。請注意,CPython 沒有針對計算進行優化x**2:內部 CPython 計算pow(x, 2, None)是計算模冪的函式(盡管呼叫pow的效率有點低,因為 CPython 必須檢查pow沒有被覆寫)。這種模冪函式要昂貴得多,因為它是一個非常通用的函式x * x。
最后,它會出現long_mul并long_pow在您的情況下被呼叫(請注意,內部long_pow呼叫實際上需要計算更多指令)。long_mullong_pow
對于大數,CPython 使用Karatsuba 乘法(請參閱:k_mul)。
請注意,CPython 在這兩種情況下實際上都非常慢,因為它需要幾納秒(至少在我的機器上)并且執行數十次檢查和許多函式呼叫只是為了將兩個整數相乘。對于主流 x86-64 處理器上的 64 位整數,這可以在 1 個周期內完成。大整數不能由主流處理器本地計算,并且需要更昂貴的計算。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/472518.html
