¿Por qué la vectorización es más rápida?

He estado aprendiendo R por un tiempo y he encontrado muchos consejos para programar tipos como yo para vectorizar operaciones. Siendo programador, me interesa por qué / cómo es más rápido. Un ejemplo:

n = 10^7
# populate with random nos
v=runif(n)
system.time({vv<-v*v; m<-mean(vv)}); m
system.time({for(i in 1:length(v)) { vv[i]<-v[i]*v[i] }; m<-mean(vv)}); m

Esto dio

   user  system elapsed 
   0.04    0.01    0.07 
[1] 0.3332091

   user  system elapsed 
  36.68    0.02   36.69 
[1] 0.3332091

Lo más obvio a considerar es que estamos ejecutando código nativo, es decir, código de máquina compilado desde C o C ++, en lugar de código interpretado, como lo demuestra la enorme diferencia en el tiempo del usuario entre los dos ejemplos (alrededor de 3 órdenes de magnitud). ¿Pero está pasando algo más? Por ejemplo, R hace:

Astucia de estructuras de datos nativos, por ejemplo. ¿Maneras inteligentes de almacenar vectores dispersos o matrices para que solo hagamos multiplicaciones cuando necesitamos?

Evaluación perezosa, por ej. en una matriz, multiplique, no evalúe las celdas hasta que lo necesite.

Procesamiento en paralelo.

Algo más.

Para probar si podría haber alguna optimización de vectores dispersos, intenté hacer productos de puntos con contenidos de vectores de diferencia

# populate with random nos
v<-runif(n)
system.time({m<-v%*%v/n}); m
# populate with runs of 1 followed by 99 0s
v <-rep(rep(c(1,rep(0,99)),n/100))
system.time({m<-v%*%v/n}); m
# populate with 0s
v <-rep(0,n)
system.time({m<-v%*%v/n}); m

Sin embargo, no hubo diferencias significativas en el tiempo (alrededor de 0.09 transcurridos)

(Pregunta similar para Matlab:¿Por qué el código vectorizado se ejecuta más rápido que para los bucles en MATLAB?)

Respuestas a la pregunta(3)

Su respuesta a la pregunta