¿Cuál es la forma recomendada de iterar una matriz sobre filas?


Dada una matriz m = [10i+j for i=1:3, j=1:4], puedo iterar sobre sus filas cortando la matriz:

for i=1:size(m,1)
    print(m[i,:])
end

Es esta la única posibilidad? Es la forma recomendada?

¿Y qué hay de las comprensiones? ¿Cortar es la única posibilidad de iterar sobre las filas de una matriz?

[ sum(m[i,:]) for i=1:size(m,1) ]
 36
Author: Nico, 2014-02-14

2 answers

La solución que usted mismo enumeró, así como mapslices, ambos funcionan bien. Pero si por " recomendado "lo que realmente quieres decir es" alto rendimiento", entonces la mejor respuesta es: no iteres sobre filas.

El problema es que, dado que los arrays se almacenan en orden mayor de columna, para cualquier cosa que no sea una matriz pequeña, terminará con una pobre relación de aciertos de caché si recorre el array en orden mayor de fila.

Como se señala en un excelente entrada de blog , si desea resumir filas, su mejor apuesta es hacer algo como esto:

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

Atravesamos tanto m como msum en su orden de almacenamiento nativo, por lo que cada vez que cargamos una línea de caché usamos todos los valores, lo que produce una relación de aciertos de caché de 1. Podría pensar ingenuamente que es mejor recorrerlo en orden de fila mayor y acumular el resultado a una variable tmp, pero en cualquier máquina moderna la falta de caché es mucho más cara que la búsqueda msum[i].

Muchos de los algoritmos internos de Julia que toman un region parámetro, como sum(m, 2), manejar esto para usted.

 44
Author: tholy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-25 19:40:48

Según mis experiencias, las iteraciones explícitas son mucho más rápidas que las comprensiones.

E iterar sobre columnas también son un buen consejo.

Además, puede usar las nuevas macros @simd y @inbounds para acelerarlo aún más.

 2
Author: Sisyphuss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 16:36:37