Итак, я работаю над кодированием программы, которая требует от меня назначать и инвертировать большую матрицу M размером 100 x 100 каждый раз в цикле, который повторяется примерно 1000 раз.
Первоначально я использовал функцию inv (), но, поскольку это занимает много времени, я хочу оптимизировать свою программу, чтобы она работала быстрее.Поэтому я написал некоторый фиктивный код для проверки того, что может замедлить процесс:
function test1()
for i in (1:100)
?=Diagonal(rand(100))
inverse_?=inv(B)
end
end
using BenchmarkTools
@benchmark test1()
---------------------------------
BenchmarkTools.Trial:
memory estimate: 178.13 KiB
allocs estimate: 400
--------------
minimum time: 67.991 μs (0.00% GC)
median time: 71.032 μs (0.00% GC)
mean time: 89.125 μs (19.43% GC)
maximum time: 2.490 ms (96.64% GC)
--------------
samples: 10000
evals/sample: 1
Когда я использую оператор '\' для оценки обратного:
function test2()
for i in (1:100)
?=Diagonal(rand(100))
inverse_?=?\Diagonal(ones(100))
end
end
using BenchmarkTools
@benchmark test2()
-----------------------------------
BenchmarkTools.Trial:
memory estimate: 267.19 KiB
allocs estimate: 600
--------------
minimum time: 53.728 μs (0.00% GC)
median time: 56.955 μs (0.00% GC)
mean time: 84.430 μs (30.96% GC)
maximum time: 2.474 ms (96.95% GC)
--------------
samples: 10000
evals/sample: 1
Я могуобратите внимание, что inv () занимает меньше памяти, чем оператор '\', хотя оператор '\' в конце быстрее.
Это потому, что я использую дополнительную матрицу идентичности -> Диагональ (единицы)(100)) в test2 ()?Означает ли это, что каждый раз, когда я запускаю свой цикл, для хранения матрицы идентификаторов выделяется новая часть памяти?
Моя исходная матрица ? является трехугольной матрицей.Стоит ли переворачивать матрицу с таким большим количеством нулей больше памяти?Для такой матрицы, что лучше использовать: функцию inv () или '\', или есть какая-то другая лучшая стратегия?
PS: Как инвертирующие матрицы в julia сравниваются с другими языками, такими как C и Python?Когда я запустил тот же алгоритм в моей более старой программе, написанной на C, это заняло значительно меньше времени ... поэтому мне было интересно, была ли здесь функция inv ().
EDIT:
Итак, как было указано, я сделал опечатку при вводе функции test1 ().Это на самом деле
function test1()
for i in (1:100)
?=Diagonal(rand(100))
inverse_?=inv(?)
end
end
Однако моя проблема осталась прежней, функция test1 () выделяет меньше памяти, но занимает больше времени:
using BenchmarkTools
@benchmark test1()
>BenchmarkTools.Trial:
memory estimate: 178.13 KiB
allocs estimate: 400
--------------
minimum time: 68.640 μs (0.00% GC)
median time: 71.240 μs (0.00% GC)
mean time: 90.468 μs (20.23% GC)
maximum time: 3.455 ms (97.41% GC)
samples: 10000
evals/sample: 1
using BenchmarkTools
@benchmark test2()
BenchmarkTools.Trial:
memory estimate: 267.19 KiB
allocs estimate: 600
--------------
minimum time: 54.368 μs (0.00% GC)
median time: 57.162 μs (0.00% GC)
mean time: 86.380 μs (31.68% GC)
maximum time: 3.021 ms (97.52% GC)
--------------
samples: 10000
evals/sample: 1
Я также проверил некоторые другиеварианты функции test2 ():
function test3()
for i in (1:100)
?=Diagonal(rand(100))
?=Diagonal(ones(100))
inverse_?=?\?
end
end
function test4(?)
for i in (1:100)
?=Diagonal(rand(100))
inverse_?=?\?
end
end
using BenchmarkTools
@benchmark test3()
>BenchmarkTools.Trial:
memory estimate: 267.19 KiB
allocs estimate: 600
--------------
minimum time: 54.248 μs (0.00% GC)
median time: 57.120 μs (0.00% GC)
mean time: 86.628 μs (32.01% GC)
maximum time: 3.151 ms (97.23% GC)
--------------
samples: 10000
evals/sample: 1
using BenchmarkTools
@benchmark test4(Diagonal(ones(100)))
>BenchmarkTools.Trial:
memory estimate: 179.02 KiB
allocs estimate: 402
--------------
minimum time: 48.556 μs (0.00% GC)
median time: 52.731 μs (0.00% GC)
mean time: 72.193 μs (25.48% GC)
maximum time: 3.015 ms (97.32% GC)
--------------
samples: 10000
evals/sample: 1
test2 () и test3 () эквивалентны.Я понял, что могу выполнить дополнительное выделение памяти в test2 (), передав вместо этого матрицу идентификации как переменную, как это было сделано в test4 ().Это также ускоряет функцию.