@ Ответ DSM является хорошим. Здесь есть несколько вещей, которые я хотел бы затронуть, кроме того. Причина, по которой ваш цикл слишком медленный, заключается в том, что A
является непостоянной глобальной переменной, и ваш код напрямую мутирует этот глобальный. Поскольку A
непостоянен, код должен защищать от возможности A
, становясь другим значением с другим типом в любой момент во время выполнения цикла. Код должен искать тип и расположение A
на каждой итерации цикла и динамически отправлять вызовы методов в выражении A[ii, jj] = A[ii, jj] + 1.0
- это вызов getindex
, +
и setindex!
, все из которых зависят от статически неизвестного типа A
, Вы можете сразу же получить гораздо более высокую производительность, просто делаю эту работу в функции:
julia> A = rand(2^10, 2^10);
julia> @time for jj = 1:size(A, 2), ii = 1:size(A, 1)
A[ii, jj] += 1
end
elapsed time: 0.288340785 seconds (84048040 bytes allocated, 15.59% gc time)
julia> function inc!(A)
for jj = 1:size(A, 2), ii = 1:size(A, 1)
A[ii, jj] += 1
end
end
inc! (generic function with 1 method)
julia> @time inc!(A)
elapsed time: 0.006076414 seconds (171336 bytes allocated)
julia> @time inc!(A)
elapsed time: 0.000888457 seconds (80 bytes allocated)
избежать неконстантых глобал как это первая рекомендация в Performance Tips разделе руководства. Возможно, вам захочется ознакомиться с остальной частью этой главы.
Далее мы можем улучшить работу функции inc!
с помощью @inbounds
аннотацию, чтобы указать, что ограничивает проверка не является необходимой для этого кода, а также с использованием линейной индексации вместо двумерный индексации:
julia> function inc!(A)
@inbounds for i = 1:length(A)
A[i] += 1
end
end
inc! (generic function with 1 method)
julia> @time inc!(A)
elapsed time: 0.000637934 seconds (80 bytes allocated)
Большая часть ускорения связана с аннотацией @inbounds
, а не с линейной индексацией, хотя это дает небольшое ускорение скорости. Однако аннотацию @inbounds
следует использовать экономно, и только там, где каждый уверен, что индексирование не может быть вне пределов и производительности, имеет первостепенное значение. Как вы можете видеть, дополнительное улучшение производительности, хотя и существующее, не является ошеломляющим. Большая часть выгоды исходит не от прямого изменения глобальных переменных.
Также стоит отметить, что значительная часть времени и памяти, используемых 'broadcast!', - это компиляция; запустите его во второй раз, и вы увидите значительное уменьшение в обоих. – tholy