Прежде всего, я предполагаю, что вы имели в виду
function assign1()
e = zeros(100, 90000)
e2 = ones(100) * 0.16
e[:, 100:end] .= e2[:]
return e # <- important!
end
Поскольку в противном случае вы не вернете первые 99 столбцов e
(!):
julia> size(assign())
(100, 89901)
Во-вторых, не делайте этого:
e[:, 100:end] .= e2[:]
e2[:]
делает копию e2
и назначает ее, но почему? Просто назначьте e2
напрямую:
e[:, 100:end] .= e2
Хорошо, но давайте попробуем несколько разных версий. Обратите внимание, что нет необходимости делать 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
Время для сравнения
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)
Версии 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)
Урок состоит в том, чтобы избегать ненужной работы.