Étant donné une matrice m = [10i+j for i=1:3, j=1:4]
, Je peux parcourir ses lignes en découpant la matrice:
for i=1:size(m,1)
print(m[i,:])
end
Est-ce la seule possibilité? Est-ce la voie recommandée?
Et qu'en est-il des compréhensions? Le découpage est-il la seule possibilité d'itérer sur les lignes d'une matrice?
[ sum(m[i,:]) for i=1:size(m,1) ]
La solution que vous avez répertoriée vous-même, ainsi que mapslices
, fonctionnent toutes les deux correctement. Mais si par "recommandé" ce que vous entendez vraiment par "hautes performances", alors la meilleure réponse est: ne pas parcourir les lignes.
Le problème est que, puisque les tableaux sont stockés dans l'ordre des colonnes, pour tout autre chose qu'une petite matrice, vous vous retrouverez avec un mauvais taux d'accès au cache si vous parcourez le tableau dans l'ordre des lignes principales.
Comme indiqué dans un excellent article de blog , si vous voulez faire la somme des lignes, votre meilleur pari est de faire quelque chose comme ceci:
msum = zeros(eltype(m), size(m, 1))
for j = 1:size(m,2)
for i = 1:size(m,1)
msum[i] += m[i,j]
end
end
Nous parcourons à la fois m
et msum
dans leur ordre de stockage natif, donc chaque fois que nous chargeons une ligne de cache, nous utilisons toutes les valeurs, ce qui donne un taux d'accès au cache de 1. Vous pourriez naïvement penser que c'est mieux pour le parcourir dans l'ordre des lignes principales et accumuler le résultat dans une variable tmp
, mais sur toute machine moderne, le cache manquant est beaucoup plus cher que la recherche msum[i]
.
De nombreux algorithmes internes de Julia qui prennent un paramètre region
, comme sum(m, 2)
, gèrent cela pour vous.
Depuis Julia 1.1, il existe des utilitaires d'itérateur pour itérer sur les colonnes ou les lignes d'une matrice. Pour parcourir les lignes:
M = [1 2 3; 4 5 6; 7 8 9]
for row in eachrow(af)
println(row)
end
Sortira:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
D'après mes expériences, les itérations explicites sont beaucoup plus rapides que les compréhensions.
Et itérer sur des colonnes est également un bon conseil.
En outre, vous pouvez utiliser les nouvelles macros @simd et @inbounds pour l'accélérer davantage.