我有这样的事情(简单的例子):
using BenchmarkTools
function assign()
e = zeros(100, 90000)
e2 = ones(100) * 0.16
e[:, 100:end] .= e2[:]
end
@benchmark assign()
Run Code Online (Sandbox Code Playgroud)
并且需要数千个时间步长。这给
BenchmarkTools.Trial:
memory estimate: 68.67 MiB
allocs estimate: 6
--------------
minimum time: 16.080 ms (0.00% GC)
median time: 27.811 ms (0.00% GC)
mean time: 31.822 ms (12.31% GC)
maximum time: 43.439 ms (27.66% GC)
--------------
samples: 158
evals/sample: 1
Run Code Online (Sandbox Code Playgroud)
有没有更快的方法来做到这一点?
首先我会假设你的意思是
function assign1()
e = zeros(100, 90000)
e2 = ones(100) * 0.16
e[:, 100:end] .= e2[:]
return e # <- important!
end
Run Code Online (Sandbox Code Playgroud)
否则您将不会返回e(!)的前 99 列:
julia> size(assign())
(100, 89901)
Run Code Online (Sandbox Code Playgroud)
其次,不要这样做:
e[:, 100:end] .= e2[:]
Run Code Online (Sandbox Code Playgroud)
e2[:]复制e2并分配它,但为什么呢?e2直接赋值即可:
e[:, 100:end] .= e2
Run Code Online (Sandbox Code Playgroud)
好的,但让我们尝试几个不同的版本。请注意,不需要制作e2向量,只需分配一个标量:
function assign2()
e = zeros(100, 90000)
e[:, 100:end] .= 0.16 # Just broadcast a scalar!
return e
end
function assign3()
e = fill(0.16, 100, 90000) # use fill instead of writing all those zeros that you will throw away
e[:, 1:99] .= 0
return e
end
function assign4()
# only write exactly the values you need!
e = Matrix{Float64}(undef, 100, 90000)
e[:, 1:99] .= 0
e[:, 100:end] .= 0.16
return e
end
Run Code Online (Sandbox Code Playgroud)
基准测试时间
julia> @btime assign1();
14.550 ms (5 allocations: 68.67 MiB)
julia> @btime assign2();
14.481 ms (2 allocations: 68.66 MiB)
julia> @btime assign3();
9.636 ms (2 allocations: 68.66 MiB)
julia> @btime assign4();
10.062 ms (2 allocations: 68.66 MiB)
Run Code Online (Sandbox Code Playgroud)
版本 1 和 2 同样快,但您会注意到有 2 个分配而不是 5 个,但是,当然,大分配占主导地位。
版本 3 和 4 更快,但不是很明显,但您会看到它避免了一些重复工作,例如将值写入矩阵两次。版本 3 是最快的,但不是很多,但是如果分配更加平衡,这种情况会发生变化,在这种情况下,版本 4 更快:
function assign3_()
e = fill(0.16, 100, 90000)
e[:, 1:44999] .= 0
return e
end
function assign4_()
e = Matrix{Float64}(undef, 100, 90000)
e[:, 1:44999] .= 0
e[:, 45000:end] .= 0.16
return e
end
julia> @btime assign3_();
11.576 ms (2 allocations: 68.66 MiB)
julia> @btime assign4_();
8.658 ms (2 allocations: 68.66 MiB)
Run Code Online (Sandbox Code Playgroud)
教训是避免做不必要的工作。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |