En mi aplicación C#, tengo una gran estructura (176 bytes) que se transfiere potencialmente cien mil veces por segundo a una función. Esta función simplemente toma un puntero a la estructura y pasa el puntero a un código no administrado. Ni la función ni el código no administrado harán modificaciones a la estructura.En .Net, ¿cuándo debo pasar las estructuras por referencia por motivos de rendimiento?
Mi pregunta es, ¿debería pasar la estructura a la función por valor o por referencia? En este caso particular, mi suposición es que pasar por referencia sería mucho más rápido que empujar 176 bytes en la pila de llamadas, a menos que el JIT reconozca que la estructura nunca se modifica (mi suposición es que no puede reconocer esto ya que la estructura la dirección se pasa al código no administrado) y optimiza el código.
Dado que estamos en ello, también vamos a contestar el caso más general en que la función hace no pasar el puntero del struct de código no administrado, sino que realiza alguna operación de sólo lectura en el contenido de la estructura. ¿Sería más rápido pasar la estructura por referencia? En este caso, ¿el JIT reconocería que la estructura nunca se modifica y, por lo tanto, se optimiza? Presumiblemente es no más eficiente pasar una estructura de 1 byte por referencia, pero ¿a qué tamaño de estructura se vuelve mejor pasar una estructura por referencia, si es que alguna vez?
Gracias.
EDIT:
Como se señala más adelante, también es posible crear una clase de "equivalente" para el uso regular, y luego usar una estructura al pasar a código no administrado. Veo dos opciones aquí:
1) Cree una clase "envoltorio" que simplemente contenga la estructura, y luego ancle y pase un puntero a la estructura al código no administrado cuando sea necesario. Un posible problema que veo es que pinning tiene sus propias consecuencias en el rendimiento.
2) Cree una clase equivalente cuyos campos se copian en la estructura cuando se necesita la estructura. Pero la copia tomaría mucho tiempo y me parece que para derrotar el punto de pasar por referencia en primer lugar.
EDIT:
Como se ha mencionado un par de veces por debajo, no me resultaba difícil simplemente medir el rendimiento de cada uno de estos métodos. I haga esto y publique los resultados. Sin embargo, todavía estoy interesado en ver las respuestas y los razonamientos de las personas desde una perspectiva intelectual.
Pregunta interesante. Por supuesto, la respuesta obvia es que la situación de cada persona es diferente, no debe optimizarla prematuramente, y debe perfilar su aplicación si va a intentar aumentar el rendimiento. Dicho esto, tengo curiosidad acerca de algunas respuestas reales. –
Esa es una estructura bastante grande, ¿por qué no convertirla en una clase? Si vas a pasarlo por ref, de todos modos se pierde el propósito de convertirlo en una estructura. –
Un puntero a esta estructura se pasa directamente a un controlador de dispositivo de hardware, por lo que sí, debe ser una estructura. Mantenerlo como una estructura y simplemente obtener un puntero es, supongo, mucho más rápido que ordenar un objeto equivalente. –