當時一開始只是自己在寫loop時,發現全域變數在for-loop當中無法被改變,查看了官方文件之後,才知道原來是scope的問題。不過後來自己陸續在Julia的forum裡頭看到有人在抱怨討論這個issue,可見得這個新的規範大家還在適應中啊 XD。
今天我在讀官方文件的Performance Tips時,又再度看到scope的正確使用是多麼地重要啊。
比如說,一個全域變數有沒有使用global
開頭來宣告就會對程式的運行效率有很大的影響
x = rand(1000)
global y = rand(1000)
function sum_all()
s = 0.0
for i in x::Vector{Float64}
s += i
end
return s
end
function sum_all_global()
s = 0.0
for i in y::Vector{Float64}
s += i
end
return s
end
println("Test sum_all()")
@time sum_all()
println("Test sum_all_global()")
@time sum_all_global()
執行這段程式碼,我們可以發現第一個版本(沒有使用global
宣告)所需執行時間稍微長一些,但所花費的記憶體開銷卻大的多。所以官方文件基本上是建議大家盡量避免使用全域變數,或是真的要用的話就把這些全域變數用常數來宣告或當成參數傳給那些函數,像這樣:
function sum_all_with_para(x::Vector{Float64})
s = 0.0
for i in x
s += i
end
return s
end
function sum_all_global_with_para(y::Vector{Float64})
s = 0.0
for i in y
s += i
end
return s
end
很明顯的,改成第二種版本後,記憶體的開銷馬上就降低成與加了global
的版本一樣了。但還是很奇怪,怎麼一個簡單的for-loop會需要allocate這麼多次的記憶體呢? 官方文件說是因為我們在global scope
裡頭用到@time
這個macro
,將它放到一個function
當中就不會了,所以我再將程式改成這樣:
time_sum_all(x) = @time sum_all_with_para(x)
time_sum_all_global(x) = @time sum_all_global_with_para(x)
println("Test time_sum_all_with_para(x)")
time_sum_all(x)
println("Test time_sum_all_global_with_para(x)")
這才叫Julia要飛起來了啊
!
關於怎麼提昇Julia performance的方式,官方文件另外給出了一些建議:
有興趣的朋友可以自行上去看看。
對於第1段的程式,比較好的用法應該是
x = rand(1000)
function sum_all()
s = 0.0
for i in x
s += i
end
return s
end
function sum_all_global()
s = 0.0
global x
for i in x
s += i
end
return s
end
println("Test sum_all(): ", @time sum_all())
println("Test sum_all_global(): ", @time sum_all_global())
哇~ 原來可以這樣寫
應該是說,global 是用來標註這個變數是全域變數來的還是區域變數來的。