我在 Python/Numpy 中使用了一個函式來解決組合博弈論中的一個問題。
import numpy as np
from time import time
def problem(c):
start = time()
N = np.array([0, 0])
U = np.arange(c)
for _ in U:
bits = np.bitwise_xor(N[:-1], N[-2::-1])
N = np.append(N, np.setdiff1d(U, bits).min())
return len(*np.where(N==0)), time()-start
problem(10000)
然后我在 Julia 中撰寫它,因為我認為由于 Julia 使用即時編譯它會更快。
function problem(c)
N = [0]
U = Vector(0:c)
for _ in U
elems = N[1:length(N)-1]
bits = elems .? reverse(elems)
push!(N, minimum(setdiff(U, bits)))
end
return sum(N .== 0)
end
@time problem(10000)
但是第二個版本要慢得多。對于 c = 10000,Python 版本需要 2.5 秒。在 Core i5 處理器上,Julia 版本需要 4.5 秒。由于 Numpy 操作是用 C 實作的,我想知道 Python 是否確實更快,或者我正在撰寫一個浪費時間復雜度的函式。
Julia 中的實作分配了大量記憶體。如何減少分配次數以提高其性能?
uj5u.com熱心網友回復:
可以通過以下方式重寫原始代碼:
function problem2(c)
N = zeros(Int, c 2)
notseen = falses(c 1)
for lN in 1:c 1
notseen .= true
@inbounds for i in 1:lN-1
b = N[i] ? N[lN-i]
b <= c && (notseen[b 1] = false)
end
idx = findfirst(notseen)
isnothing(idx) || (N[lN 1] = idx-1)
end
return count(==(0), N)
end
首先檢查函式是否產生相同的結果:
julia> problem(10000), problem2(10000)
(1475, 1475)
(我還檢查了生成的N向量是否相同)
現在讓我們對這兩個函式進行基準測驗:
julia> using BenchmarkTools
julia> @btime problem(10000)
4.938 s (163884 allocations: 3.25 GiB)
1475
julia> @btime problem2(10000)
76.275 ms (4 allocations: 79.59 KiB)
1475
因此,它的速度提高了 60 倍以上。
我為提高性能所做的就是避免分配。在 Julia 中,它既簡單又高效。如果代碼的任何部分不清楚,請發表評論。請注意,我專注于展示如何提高 Julia 代碼的性能(而不是試圖僅僅復制 Python 代碼,因為 - 正如在原始帖子下所評論的那樣 - 進行語言性能比較非常棘手)。我認為最好集中討論如何使 Julia 代碼更快。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/415229.html
標籤:
上一篇:為什么5<=-15==5>=1!=20是假的?[復制]
下一篇:凱撒密碼不加密
