Julia 學習筆記 - 計時

延伸閱讀: Julia 學習筆記 - 簡介, 畫圖, 計時


這裡我們要介紹 julia 計算程式執行時間的指令.

簡單來說,julia 計算程式運行效能有幾個指令:

  • @time 顯示出程式運行的秒數以及記憶體的使用狀況
  • @timed 顯示程式執行回傳值,秒數以及記憶體的使用狀況
  • @timev 顯示@time一樣的資訊,最後顯示程式執行回傳值
  • @elapsed 顯示出某程式運行的秒數

BUT, 真正要計算程式效能, 還是推薦用 BenchmarkTools.jl 這個 package.

以下範例中我們需要使用兩個 package: LinearAlgebra 以及 BenchmarkTools

using LinearAlgebra
using BenchmarkTools

Example 1: Matrix-matrix multiplication

我們以矩陣乘法 $C=A\times B$ 為例:$A:n\times p$, $B:p\times m$, $C:n\times m$

f1 這個函數會產生兩個隨機矩陣 $A$, $B$ 並且將他們相乘:

function f1(n, p, m)
   A=rand(n,p)
   B=rand(p,m)
   C=zeros(Float64,n,m)
   for i in 1:n
      for j in 1:m
         for k in 1:p
            C[i,j] = C[i,j]+A[i,k]*B[k,j]
         end
       end
    end
end
f1 (generic function with 1 method)

我們先試試看以 julia 既有的計算時間指令來看結果如何

@time f1(100,10,200)
  0.076423 seconds (161.79 k allocations: 8.380 MiB)
@timed f1(100,10,200)
(nothing, 0.000448109, 184496, 0.0, Base.GC_Diff(184496, 1, 0, 5, 2, 0, 0, 0, 0))
@timev f1(100,10,200)
  0.005932 seconds (8 allocations: 180.172 KiB, 92.28% gc time)
elapsed time (ns): 5931535
gc time (ns):      5473727
bytes allocated:   184496
pool allocs:       5
non-pool GC allocs:2
malloc() calls:    1
GC pauses:         1
@elapsed f1(100,10,200)
0.000561533

這些指令的表現如同一開始我們所介紹的, 顯示出程式執行時間以及其他資訊.

不過一般而言一個程式在第一次跑及之後幾次跑的運行效能會不同, 這是由於初始化的關係. 所以我們通常要跑好幾次來算平均, 已得知一個程式的真正效能.

benchmark 就提供了這樣的功用, 他會跑好幾次程式, 並且計算最大最小時間.

@benchmark f1(100,10,200)
BenchmarkTools.Trial:
  memory estimate:  180.02 KiB
  allocs estimate:  4
  --------------
  minimum time:     437.243 μs (0.00% GC)
  median time:      485.922 μs (0.00% GC)
  mean time:        513.114 μs (3.90% GC)
  maximum time:     44.383 ms (98.89% GC)
  --------------
  samples:          9711
  evals/sample:     1

接著我們看一下如果用 LinearAlgebra 裡的矩陣乘法指令效能如何.

function f2(n, p, m)
    A=rand(n,p)
    B=rand(p,m)
    C=zeros(Float64,n,m)
    mul!(C,A,B);
end
f2 (generic function with 1 method)
@benchmark f2(100,10,200)
BenchmarkTools.Trial:
  memory estimate:  180.02 KiB
  allocs estimate:  4
  --------------
  minimum time:     41.088 μs (0.00% GC)
  median time:      91.270 μs (0.00% GC)
  mean time:        106.954 μs (19.04% GC)
  maximum time:     45.286 ms (99.75% GC)
  --------------
  samples:          10000
  evals/sample:     1

看起來似乎比我們自己寫的 for-loop 效能好一些.


type-stability

julia 語言號稱效能非常好, 不過常常我們自己寫一個 julia 程式發現跑得沒有很快, 這通常是由於所謂的 “型別穩定性 type-stability”. 這樣的問題可以藉由以下幾個 julia 內建的巨集程式來診斷.

@code_warntype f1(10,10,10)
@code_typed f1(10,10,10)
@code_native f1(10,10,10)

這方面更深入的說明可見 julia: performance tips


Example 2: Vector 2-norm

接著我們看一下算向量 2-norm 的效能, 一樣我們比較一下自己寫的以及 call 函數的方式.

function t1(n)
    vec = rand(1,n);
    vec*vec';
end
t1 (generic function with 1 method)
@benchmark t1(10^5)
BenchmarkTools.Trial:
  memory estimate:  781.42 KiB
  allocs estimate:  3
  --------------
  minimum time:     423.973 μs (0.00% GC)
  median time:      504.538 μs (0.00% GC)
  mean time:        606.699 μs (9.87% GC)
  maximum time:     47.376 ms (98.43% GC)
  --------------
  samples:          8213
  evals/sample:     1
function t2(n)
    vec = rand(1,n);
    sum(abs2, vec);
end
t2 (generic function with 1 method)
@benchmark t2(10^5)
BenchmarkTools.Trial:
  memory estimate:  781.33 KiB
  allocs estimate:  2
  --------------
  minimum time:     141.160 μs (0.00% GC)
  median time:      195.940 μs (0.00% GC)
  mean time:        335.496 μs (19.51% GC)
  maximum time:     64.500 ms (99.17% GC)
  --------------
  samples:          10000
  evals/sample:     1

Example 3: Solving linear system

這裡我們看一下解線性系統, 也就是 matlab 常見的"左除", 的效率如何.

function s1(n)
    A=rand(n,n);
    b=rand(n);
    A\b;
end
s1 (generic function with 1 method)
@benchmark s1(1000)
BenchmarkTools.Trial:
  memory estimate:  15.28 MiB
  allocs estimate:  8
  --------------
  minimum time:     13.463 ms (0.00% GC)
  median time:      16.817 ms (10.20% GC)
  mean time:        18.148 ms (9.36% GC)
  maximum time:     64.226 ms (77.63% GC)
  --------------
  samples:          276
  evals/sample:     1

Avatar
Te-Sheng Lin (林得勝)
Professor

The focus of my research is concerned with the development of analytical and computational tools, and further to communicate with scientists from other disciplines to solve engineering problems in practice.

Related