2012-09-13 11 views
6

En el siguiente código de ejemplo, asigno algunas instancias del struct Chunk. En los bucles for, repito a través del bloque de memoria y accedo a las diferentes instancias usando puntero o referencias, y les asigno algunos datos aleatorios.¿Cuál es más rápido, acceso a puntero o acceso de referencia?

Pero, ¿cuál de los bucles se ejecutará más rápido? Por lo que sé, diría que el lazo de referencia será el más rápido porque no requerirá desreferenciación y tiene acceso directo a la instancia en la memoria. ¿Qué tan equivocado/correcto soy?

struct Chunk { 
    unsigned int a; 
    float b; 
    const char* c; 
}; 

int main() { 
    Chunk* pData = new Chunk[8]; 

    for(unsigned int i = 0; i < 8; ++i) { 
     Chunk* p = &pData[i]; 
     p->a = 1; 
     p->b = 1.0f; 
     p->c = "POINTERS"; 
    } 

    for(unsigned int i = 0; i < 8; ++i) { 
     Chunk& r = pData[i]; 
     r.a = 1; 
     r.b = 1.0f; 
     r.c = "REFERENCES"; 
    } 

    delete [] pData; 
    return 0; 
} 
+7

Depende de tu compilador, supongo, pero con el mío compilan exactamente el mismo código. La mayoría de los desarrolladores de C++ prefieren las referencias como una cuestión de estilo. –

+0

Recuerde que una referencia es como un puntero desreferenciado automáticamente. – tadman

+0

@tadman No de acuerdo con la norma. –

Respuesta

10

Deben ser los mismos (no se trata de lo mismo, pero exactamente el mismo) con cualquier compilador no idiota. Debajo del capó, las referencias son punteros (en el 99% de los compiladores). No hay razón para ninguna diferencia.

pedante: el segundo bucle podría ser más rápido (probablemente no), ya que los datos están en la memoria caché ya, pero eso es todo. :)

+0

Explicación para el downvote? –

+0

Probablemente un fanático de C al que le gustan las flechas mejor que ampersands. – tadman

+2

No es 100% correcto. Las referencias no son punteros, no son objetos en absoluto. Podrían implementarse mediante punteros en varios casos, pero no en un 100%. Y el código generado para el puntero y para referencia podría diferir. – Rost

1

No debería haber diferencia en el código producido por cualquier compilador decente.

1

Cuando dude entre dos versiones del código como las de su ejemplo, debe elegir la más legible. El compilador debe realizar una posible optimización del tipo que propone.

Cuanto más legible en su caso es la versión con referencias (en realidad, tal vez no es más legible, pero el consenso es preferir el uso de referencias porque los punteros son más "peligrosos").

Pero volvamos a la eficacia: (por favor, si alguien sabe ensamblador, mejor deja de leer o te arriesgas a un ataque de risa ...) En mi opinión, como el pData está alojado en el montón, el compilador tendrá que compilarlo usando punteros de todos modos. Creo que su razonamiento podría ser correcto si su estructura estuviera asignada en la pila solo con "Datos de fragmento [8]". Pero a más tardar cuando las optimizaciones del compilador estén encendidas, la diferencia debería eliminarse de todos modos.

1

Estoy tentado de decir: ¿a quién le importa? Cualquier diferencia en la velocidad será insignificante, y debe elegir la más legible. En este caso particular , esperaría ver exactamente el mismo código generado en ambos casos . En casos más complicados, el compilador puede no ser capaz de determinar más tarde en el bucle que el puntero no se ha vuelto a colocar, y puede tener que volver a leerlo. Pero para que este sea el caso, tendría que ser haciendo otras cosas suficientes para que la diferencia no se pueda medir.

+0

Gracias por responder. Esto es, como habrán notado, no un ejemplo del mundo real. Me pregunto qué debería elegir en un escenario más complejo. –

+0

@MichaelMancilla El que mejor exprese lo que quiere hacer. Generalmente, referencia cuando sea posible, y puntero de lo contrario. El uso de la referencia le dice al lector (y al compilador) que el objeto referido no cambiará. –

+0

"Cualquier diferencia en la velocidad será insignificante", su caso de uso no es de nadie más. – easytiger

Cuestiones relacionadas