#julia
#julia
Вопрос:
У меня простой вопрос. Я определил структуру, и мне нужно инициализировать их много (порядка миллионов) и перебирать их.
Я инициирую по одному и выполняю цикл следующим образом:
using Distributions
mutable struct help_me{Z<:Bool}
can_you_help_me::Z
millions_of_thanks::Z
end
for i in 1:max_iter
tmp_help = help_me(rand(Bernoulli(0.5),1)[1],rand(Bernoulli(0.99),1)[1])
# many follow-up processes
end
Распределение памяти увеличивается в max_iter. Для моей цели мне не нужно сохранять каждую структуру. Есть ли способ «повторно использовать» выделение памяти, используемое структурой?
Комментарии:
1. Вопрос 1: зачем вы это делаете
Z<:Bool
?Bool
это уже конкретный тип? Вопрос 2: какая-либо причинаhelp_me
должна бытьmutable
? неизменяемые структуры часто дешевле. кромеrng
того, явная передача вrand
может дать вам простое ускорение в 2 раза. (из-за соображений безопасности многопоточности)2. Привет, Osca, спасибо за вопросы. 1. Не знал. Спасибо. 2. Это может быть не так на самом деле. Спасибо. Я все еще разрабатываю процессы, которые должен пройти каждый агент. 3. Не знал. Спасибо. Есть ли решение проблемы выделения памяти?
3. Я думаю, что создание структуры не
mutable
исправит это. неизменяемые объекты могут быть выделены стеком (в большинстве случаев), поэтому их создание и уничтожение должны быть в основном бесплатными.
Ответ №1:
Ваша основная проблема заключается здесь:
rand(Bernoulli(0.5),1)[1], rand(Bernoulli(0.99),1)[1]
Вы создаете массив длиной 1, а затем считываете первый элемент из этого массива. Это выделяет ненужную память и требует времени. Не создавайте здесь массив. Вместо этого напишите
rand(Bernoulli(0.5)), rand(Bernoulli(0.99))
Это просто создаст случайные скалярные числа, а не массив.
Сравните тайминги здесь:
julia> using BenchmarkTools
julia> @btime rand(Bernoulli(0.5),1)[1]
36.290 ns (1 allocation: 96 bytes)
false
julia> @btime rand(Bernoulli(0.5))
6.708 ns (0 allocations: 0 bytes)
false
в 6 раз быстрее и без выделения памяти.
Похоже, это общая проблема. Очень часто я вижу, как люди пишут rand(1)[1]
, когда они должны использовать just rand()
.
Кроме того, подумайте, действительно ли вам нужно создавать структуру mutable
, как упоминали другие.
Комментарии:
1. Спасибо. Очень признателен.
Ответ №2:
Если структура больше не нужна (т. Е. Нигде не упоминается за пределами текущей итерации цикла), сборщик мусора автоматически освободит свою память, если потребуется.
В противном случае я согласен с предложениями Оскара Смита: выделение памяти и сборка мусора требуют времени, избегайте этого по соображениям производительности, если это возможно.