簡體   English   中英

為什么除數的一個 function 比另一個快 > 3000%?

[英]Why is one function of divisor >3000% faster than the other?

I was doing some simple Python exercises on https://www.practicepython.org/ when I did this task https://www.practicepython.org/exercise/2014/02/26/04-divisors.html .

我想測試不同的方法來編寫答案,我在評論字段中看到了引起我興趣的解決方案; 兩個代碼看起來相似,但一個比另一個快 4000%!

代碼:

import time

start = time.time()

print("Fast code:")

#the slow code
def divisor(x):
    divisors = []
    for i in range(1, int(x)):
        if x % i == 0:
            divisors.append(i)
            divisors.sort()
    print(divisors)


divisor(50000000)
end = time.time()
print("Time elapsed: ")
print(end - start)

print("Fast code:")

start = time.time()

#the fast code!
def divisor2(x):
    divisors = []
    for i in range(1, int(x**.5)):
        if x % i == 0:
            divisors.append(i)
            divisors.append(x//i)
            divisors.sort()
    print(divisors)
divisor2(50000000)
end = time.time()
print("Time elapsed: ")
print(end - start)

經過的時間(慢代碼):

3.1739981174468994

經過的時間(快速代碼):

0.0010004043579101562

誰能告訴我這是怎么可能的,所以也許任何人都可以為他們的工具帶帶回家一些有價值的更快的編碼技能?

x**.5是 x 的半次方,它是平方根。

兩者都使用x = 50,000,000 ,第一個是:

for i in range(1, int(x)):

5000 萬次循環

第二個是:

for i in range(1, int(x**.5)):

七千圈

在計算除數時可以這樣做的原因是因為它們形成了一個矩形的兩側:

 __
|  |
|  |
|__|

如果您知道面積(目標,5000 萬),並且您知道一側(計數器i ),那么您可以計算出另一側。 兩邊相同的地方是平方根,它就像一個 pivot,如果一個比那個短,那么另一個必須更長,並平衡它。 也就是說, 100/2 = 50給你 2 和 50。

所以你可以數到平方根來找到所有簡短的答案,計算出每個答案的另一面(平衡),然后你就有了所有的答案。 100/10 = 10給你 10 作為除數,並告訴你,如果你一直數到100/50 = 2 ,你已經從另一邊看到了,得到了 50。

這就是為什么第二個代碼具有:

        divisors.append(i)
        divisors.append(x//i)

僅測試一個后,將兩個值添加到列表中。

經典 O(n) 與 O(n^0.5)

第一個是做 50000000 次操作

第二個是執行 7000 次操作(少 7000 次)

那么時差呢? 快3000倍? 有些東西沒有加起來。

這里!

divisors.sort()

您在找到每個除數對之后執行此操作,這是一項昂貴的操作。 只需將其向左移動 2 個縮進級別(與print級別相同),即可看到大約 7000 倍或更高的性能。

為什么會這樣?

好吧,如果你發現 15 可以被 3 整除,那么為什么要檢查每隔一個數字然后再檢查 5,因為你知道如果 15 可以被 3 整除,那么它也可以被 15/3 整除。 此外,任何數字都不能被任何大於其平方根的數字整除,其中結果也大於平方根。 因此,長時間運行循環是沒有意義的——它不會找到解決方案。 由於 50000000 絕對不能被任何大於 7071.067811865475 的數字整除,這將導致另一個大於 7071.067811865475 的數字,如果我們將找到的每個除數的除法結果相加,檢查 7072 和更大的數字會浪費大量時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM