#julia
#julia
Вопрос:
С Julia 1.5.3 у меня есть следующий код (конечно, это не настоящий код, просто надуманный пример, с помощью которого я мог бы воспроизвести проблему):
function basic()
result::Tuple{Int64,Int64,Int64} = (0, 0, 0)
for i in 1:100000
for i in -1:1, j in -1:1, k in -1:1
result = result . (i, j, k)
end
end
result
end
function fancy(T)
result::T = (0, 0, 0)
for i in 1:100000
for i in -1:1, j in -1:1, k in -1:1
result = result . (i, j, k)::T
end
end
result
end
# Warmup
for i in 1:10
basic()
fancy(Tuple{Int64,Int64,Int64})
end
println("basic:")
println(@time basic())
println("fancy:")
println(@time fancy(Tuple{Int64,Int64,Int64}))
выводит:
basic:
0.000000 seconds
(0, 0, 0)
fancy:
0.762599 seconds (10.80 M allocations: 494.385 MiB, 3.68% gc time)
(0, 0, 0)
Если я напишу вместо:
result = result . (i, j, k)::T
Я получаю:
basic:
0.000000 seconds
(0, 0, 0)
fancy:
0.789512 seconds (13.50 M allocations: 576.782 MiB, 3.77% gc time)
(0, 0, 0)
Есть ли способ сделать basic
и fancy
выполнить то же самое, т. Е. Без выделения fancy
?
Комментарии:
1. Вы также можете рассмотреть возможность использования
SVector
fromStaticArrays
вместо этого.
Ответ №1:
Просто измените подпись fancy
:
function fancy(::Type{T}) where T
result::T = (0, 0, 0)
for i in 1:100000
for i in -1:1, j in -1:1, k in -1:1
result = result . (i, j, k)::T
end
end
result
end
println(@time fancy(Tuple{Int64,Int64,Int64}))
Просто обратите внимание, что обе функции фактически оптимизированы для почти безоперационной работы. Вы можете проверить это с @code_native basic()
помощью .
Комментарии:
1. Спасибо, это имеет смысл. На всякий случай,
fancy(::Type{T}) where T
означает, что мы принимаем параметр, который является типом, и этот тип параметризован как T. Итак, теперь мне любопытно, что сделал код в моем вопросе:function fancy(T) result::T = (0, 0, 0) ...
что тогда было T?2. Да, в моем вопросе
T
был параметр типаAny
. Но тогда что этоresult::T
значило? Я предполагаю, что это была динамическая проверка типа во время назначения?3. ДА. На самом деле это больше похоже
result = convert(T, (0,0,0))
, чем утверждение типа.
Ответ №2:
Как насчет этого?
function fancy(T)
result = T((0, 0, 0))
for i in 1:100000
for i in -1:1, j in -1:1, k in -1:1
result = result . T((i, j, k))
end
end
result
end