Julia 語言中的生成器表示式與陣列推導式

黃志斌發表於2020-08-11

Julia 程式設計基礎》第 228 頁:

當然了,程式的好壞肯定不能單憑是否節省記憶體空間來衡量。如果我們觀測程式的執行時間(可以用 @timev 巨集),會發現生成器表示式通常還不如包含了陣列推導式的相應程式碼執行速度快。

我使用以下程式碼進行測試(程式碼中的“生成器表示式”和“陣列推導式”來源於書中同一頁):

function test(n)
  println("\n效能測試(n = $(n))")
  println("生成器表示式:")
  @timev reduce(*, (x for x=1:n))
  println("\n陣列推導式:")
  @timev reduce(*, [x for x=1:n])
end

println("Julia Version $(VERSION)")
test(10)
test(10^8)

執行結果如下:

$ julia p228.jl 
Julia Version 1.5.0

效能測試(n = 10)
生成器表示式:
  0.000000 seconds
elapsed time (ns): 62

陣列推導式:
  0.000014 seconds (1 allocation: 160 bytes)
elapsed time (ns): 13845
bytes allocated:   160
pool allocs:       1

效能測試(n = 100000000)
生成器表示式:
  0.000000 seconds
elapsed time (ns): 50

陣列推導式:
  0.335083 seconds (2 allocations: 762.940 MiB, 1.03% gc time)
elapsed time (ns): 335083357
gc time (ns):      3449954
bytes allocated:   800000080
pool allocs:       1
malloc() calls:    1
GC pauses:         1

可見,在上述程式碼中,生成器表示式比包含陣列推導式的相應程式碼執行速度快。


以下程式碼根據這本書的作者郝林老師給出陣列推導式寫成:

println("Julia Version $(VERSION)")
println("生成器表示式:")
@timev map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])
println("\n陣列推導式:")
@timev map(tuple, [1/(i+j) for i=1:2, j=1:2], [1 3; 2 4])

執行結果:

$ julia p228a.jl
Julia Version 1.5.0
生成器表示式:
  0.157070 seconds (587.07 k allocations: 31.358 MiB)
elapsed time (ns): 157069903
bytes allocated:   32880759
pool allocs:       586924
non-pool GC allocs:150

陣列推導式:
  0.112933 seconds (344.12 k allocations: 17.103 MiB, 5.04% gc time)
elapsed time (ns): 112932620
gc time (ns):      5686877
bytes allocated:   17934120
pool allocs:       344109
non-pool GC allocs:13
GC pauses:         1

可見,在上述程式碼中,生成器表示式比包含陣列推導式的相應程式碼執行速度慢。


相關文章