mapreduce
peut être beaucoup plus lent que la boucle for
équivalente. Un petit exemple ( réel ) :
function dsum(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="9">@inbounds</strong> for j in 1:n
B[j] = mapreduce(k -> A[j,k]*A[k,j], +, z, 1:j)
end
B
end
function dfor(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="10">@inbounds</strong> for j in 1:n
d = z
for k in 1:j
d += A[j,k]*A[k,j]
end
B[j] = d
end
B
end
A = randn(127,127)
time(median(<strong i="11">@benchmark</strong> dsum(A)))/time(median(<strong i="12">@benchmark</strong> dfor(A)))
me donne un ratio de performance d'environ x50 sur Julia 0.5, juliabox.com. Je pense que cela pourrait être dû au fait que la boucle for
peut être automatiquement simd
, et que mapreduce ne l'est pas? Lorsque A = randn(N,N)
et N
est 16
, l'écart est d'environ x75, et pour N = 10000
, l'écart est d'environ x25. Remplacer l'accès au tableau A[j,k]
par A[rand(1:size(A,1)),rand(1:size(A,2))]
détruit les performances des deux, mais le ratio devient x1.
simd
est la raison pour laquelle on est x50 plus rapide ?mapreduce
sous-tend sum
, donc cela pourrait être un piège populaire qui n'est pas mentionné actuellement(Benchmarking mapreduce
contre for
-boucles sans accès au tableau, je vois toujours un écart de performance x2. Par exemple, mapreduce(identity, +, 0, i for i in 1:n)
par rapport à la boucle équivalente de somme entière for
. Il semble que cet écart était plus petit ? Vaut-il une autre référence en CI ?)
Ressemble à une copie de https://github.com/JuliaLang/julia/issues/15276.
En faisant:
function dsum(A::Matrix)
z = zero(A[1,1])
n = Base.LinAlg.checksquare(A)
B = Vector{typeof(z)}(n)
<strong i="8">@inbounds</strong> for j::Int in 1:n
B[j] = _help(A, j, z)
end
B
end
_help(A, j, z) = mapreduce(k -> A[j,k]*A[k,j], +, z, 1:j)
donne
julia> time(median(<strong i="12">@benchmark</strong> dsum(A)))/time(median(<strong i="13">@benchmark</strong> dfor(A)))
1.0013213312412255
Vous pouvez voir le problème en @code_warntype
et en recherchant Core.Box
.
+1 pour avoir mis une référence de cela dans BaseBenchmarks ; un PR il serait super.
Clôture en double du #15276.
Commentaire le plus utile
+1 pour avoir mis une référence de cela dans BaseBenchmarks ; un PR il serait super.