2011-08-19 6 views
5

En cuanto al rendimiento, ¿es mejor acceder un elemento de matriz 'directamente' varias veces, o asignarle su valor a una variable y usar esa variable? Suponiendo que haré referencia al valor varias veces en el siguiente código.Acceder directamente a un elemento de matriz vs. asignarlo a una variable

El razonamiento detrás de esta pregunta es que, el acceso a un elemento de matriz presumiblemente implica algún costo de cálculo cada vez que se realiza, sin requerir espacio adicional. Por otro lado, almacenar el valor en una variable elimina este costo de acceso, pero ocupa más espacio.

// use a variable to store the value 
Temp = ArrayOfValues(0) 
If Temp > 100 Or Temp < 50 Then 
    Dim Blah = Temp 
    ... 

// reference the array element 'directly' 
If ArrayOfValues(0) > 100 Or ArrayOfValues(0) < 50 Then 
    Dim Blah = ArrayOfValues(0) 
    ... 

Sé que esto es un ejemplo trivial, pero asumiendo que estamos hablando de una escala mayor en el uso real (donde el valor se hace referencia muchas veces) en qué momento es el compromiso entre el espacio y el tiempo de computación pena ¿considerando (si es que lo hace)?

+1

Un compilador de optimización va a hacer esto totalmente discutible para los HLL. Si está utilizando el ensamblaje o tiene las optimizaciones desactivadas, los registros son más rápidos que el caché, por lo que debe cargar valores utilizados con frecuencia en los registros tanto como sea posible. En general, creo que el punto de inflexión entre la presión de registro y la jerarquía de la memoria es probablemente una cuestión empírica. – Patrick87

Respuesta

2

La sobrecarga en el consumo de memoria es muy limitada porque para los tipos de referencia es solo un puntero (par de bytes) y la mayoría de los tipos de valores también requieren unos pocos bytes.

Las matrices son estructuras muy eficientes en la mayoría de los idiomas. Llegar a un índice no implica ninguna búsqueda, sino solo algunas operaciones matemáticas (cada ranura de la matriz toma 4 bytes, por lo que la ranura 11 está en el desplazamiento 40). Entonces, probablemente haya un poco de sobrecarga para verificar los límites. Asignar la memoria para una nueva var local y liberarla también requiere un poco de ciclos de CPU. Entonces, al final también depende de cuántas búsquedas de matriz eliminas copiando en una var. Local.

El hecho es que realmente necesita un hardware excepcionalmente malo o tiene grandes loops para que esto sea realmente importante y si se ejecuta una prueba decente en él. Yo personalmente elijo a menudo la variable separada, ya que creo que hace que el código sea más legible.

Su ejemplo es extraño por cierto, ya que hace 2 búsquedas de la matriz antes de crear el var :) Esto tiene más sentido (2 de eliminación de las búsquedas más)

Dim blah = ArrayOfValues(0) 
if blah > 100 or blah < 50 then 
... 
2

Este lenguaje está marcado agnóstico, pero don Realmente creo que es así. Esta publicación responde a la versión C y C++ de la pregunta.

Un compilador de optimización puede encargarse de accesos de matriz "desnudos"; en C o C++ no hay ninguna razón para pensar que el compilador no recordaría el valor de una ubicación de memoria si no se llamaran a funciones intermedias. P.ej.

int a = myarray[19]; 
int b = myarray[19] * 5; 
int c = myarray[19]/2; 
int d = myarray[19] + 3; 

Sin embargo, si myarray no es sólo define como int [], pero es en realidad algo, especialmente algunos definida por el usuario tipo de contenedor "de lujo" con una función operator[]() definido en otra unidad de traducción, entonces esa función debe ser cada vez que se solicita el valor (ya que la función devuelve los datos en la ubicación en la memoria y la función local no sabe que el resultado de la función debe ser constante).

Incluso con matrices 'desnudas', si accedes a lo mismo varias veces en las llamadas a funciones, el compilador debe asumir que el valor ha cambiado (incluso si puede recordar la dirección). P.ej.

int a = myarray[19]; 
NiftyFunction(); 
int b = myarray[19] * 8; 

No hay manera de que el compilador puede saber que myarray [19] tendrán el mismo valor antes y después de la llamada a la función.

Por lo general, si sabe que un valor es constante a través del alcance local, "caché" en una variable local. Se puede programar la defensiva y utilizar afirmaciones para validar esta condición que ha puesto en las cosas:

int a = myarray[19]; 
NiftyFunction(); 
assert(myarray[19] == a); 
int b = a * 8; 

Una ventaja final es que es mucho más fácil de inspeccionar los valores en un depurador si no están enterrados en algún lugar en una matriz .

+1

+1 para "Esto está etiquetado como independiente del idioma, pero realmente no creo que lo sea". La respuesta de C# podría ser diferente de ciertas maneras, pero no estoy calificado para ofrecerla. – ClickRick

Cuestiones relacionadas