Юлия: Лучшая практика для мутации стабильных типов - PullRequest
0 голосов
/ 14 мая 2018

Это моя первая попытка в Джулии, поэтому, пожалуйста, прости меня, если это звучит банально для тебя. Мой код Julia уже работает намного лучше, чем мой код Python, но у меня остался вопрос, касающийся набора текста.

Для научной программы я работаю с множеством массивов, которые стабильны по типу и имеют фиксированную размерность. Программа направлена ​​на обновление этих массивов с помощью математически нетривиальной схемы, чтобы минимизировать энергетическую функцию. Я определил эти массивы в глобальной области видимости

const A = Array{Complex{Float32}}(dim)

, где dim - размерность. Я заметил, что добавление const значительно ускорило мои вычисления (в 3 раза быстрее). Впоследствии содержимое этих массивов инициализируется и обновляется в функциях A[:] =....

Является ли определение стабильных типов массивов фиксированной размерности как const s глобально, и обновление путем обращения к ним как A[:] считается плохой практикой?

Моим лучшим вариантом при альтернативном методе было бы вводить входные аргументы всех моих функций и передавать множество переменных. Это было бы более желательно?

1 Ответ

0 голосов
/ 14 мая 2018

Мое (субъективное) мнение таково, что определение их как const и последующее изменение содержимого само по себе не обязательно является плохой практикой. В Юлии ясно, что объявление const относится к привязке значения переменной, а не к внутренним значениям.

Однако, если одна и та же переменная A используется для хранения разрозненных несвязанных значений (а не разных форм одной и той же матрицы, например, приведенных форм), это, безусловно, плохая практика. A[:] .= A .* 2 нормально, A[:] .= X нет.

Кроме того, наличие нескольких глобальных переменных, которые мутируют в разных местах, обычно является запахом кода и часто приводит к неуловимым и не очень тонким ошибкам. Это также делает код сложным для рассуждения.

Как насчет инкапсуляции переменных в один тип struct, например.

struct ArrayVars 
   A::Array{Complex{Float32}, dim}
   B::Array{Float64, dim}
   ...
end

и создание экземпляра этого в функции стиля init? (Надеюсь, вы можете придумать более подходящее имя для типа, чем ArrayVars, принимая во внимание семантику задействованных массивов.) Затем вы можете передать эту единственную переменную этого типа в функции и манипулировать массивами внутри нее, вместо этого передачи много переменных для каждой функции.

...