2012-02-17 13 views
10

En C#, ¿hay alguna reducción significativa en la asignación de memoria al pasar una referencia DateTime como parámetro a una función en lugar de pasarla por valor?¿Puedo reducir la asignación de memoria pasando el parámetro DateTime por referencia en C#?

int GetDayNumber(ref DateTime date) 

vs

int GetDayNumber(DateTime date) 

El código dentro de la función no es la modificación de la fecha en cualquier caso.

+1

¿Alguna razón por la que no usaría 'date.Day'? –

+0

¿Qué significante es significativo? Un objeto DateTime no es exactamente un hogger de memoria. Lo más probable es que vaya en la pila o en un registro de todos modos, e incluso cuando pasa una referencia, sus datos de aprobación (es decir, la referencia) que pueden tener el mismo tamaño (no puede ser mucho más pequeño porque DateTime es muy pequeño). –

+0

Esta función hace algo diferente a date.Day Esta función se llama millones de veces, por lo que cualquier mejora en la misma sería excelente.Supongo que esa diferencia en la asignación de memoria en la pila es el "Tamaño de fecha y hora" - "Tamaño de referencia" – jeroko

Respuesta

12

A DateTime es una estructura de 8 bytes. A ref tiene 4 u 8 bytes dependiendo de su arquitectura de destino. Entonces, en el mejor de los casos, guardarías 4 bytes de memoria de pila, lo cual es completamente irrelevante.

Incluso es probable que ref evite algunas optimizaciones, como colocar el DateTime en un registro, aumentando así el uso de la memoria.

Este es un caso claro de optimización prematura. No hagas esto

+0

¿Qué pasa si el método se llama un millón de veces seguidas? esto depende de cuándo se libera la referencia para GC. Si es de corta duración, está bien, pero ¿qué ocurre si se mantiene durante un tiempo no desdeñable? ¿No tendría el árbitro un efecto positivo? –

+1

1) Un millón de veces seguidas no tendría ningún efecto. Tendría los mismos 8 bytes un millón de veces. Un millón de veces recursivamente sería un problema, pero rara vez se tiene una función recursiva en C#. 2) El GC no entra en esto. Un 'DateTime' local asignado en la pila no necesita que se libere el GC. Cuando la función finaliza, el puntero de la pila se ajusta y todas las variables locales verdaderas desaparecen. Esto es prácticamente gratis. | Solo se complica si las variables locales no son verdaderamente locales (captura de lamda, async-await, iteratiors de rendimiento, ...), pero ese no es el caso aquí. – CodesInChaos

1

No creo que haya una reducción significativa en el uso de la memoria, pero creo que hay algunas.

Al pasar la fecha y hora con ref no se creará un nuevo objeto de fecha y hora como cuando no se utiliza la palabra clave ref

-2

Internamente, los valores DateTime se representan como el número de garrapatas, que es mucho de 64 bits.

Un procesador de 64 bits necesitará la misma cantidad de bits para enviar la dirección de la variable.

Pero si trabaja en un procesador de 32 bits, su rango de direcciones es menor que el tamaño de la fecha y hora. Por lo tanto, el rendimiento podría mejorarse.

Sin embargo, en la práctica, la diferencia casi nunca se notará.

+0

Esto está mal, se pasa ** por valor **. Incluso si fuera un tipo de referencia, que no lo es, aún se pasaría por valor. – oleksii

+1

DateTime es una estructura, por lo que no se pasa por referencia, a menos que alguien haya cambiado C# sin decirmelo. –

+2

Usted es incorrecto, DateTime es una estructura y, por lo tanto, se pasa por valor. –

2

Al igual que con cualquier otra pregunta similar, debe cronometrarla usted mismo. ¿Podrían unos pocos ticks de procesador desempeñar un papel importante? ¿Podrían algunos bytes adicionales jugar un papel importante en el consumo de memoria en su aplicación?

Deje la micro optimización y concéntrese primero en resolver problemas reales.

0

Podría, sin embargo, dado que DateTime es una estructura y solo está asignado en la pila, hay muy poca sobrecarga ya que no hay asignación de montón como hay para una clase. Además, dado que el valor se pasa como una nueva instancia, el espacio en la pila se liberará tan pronto como salga del método.

var date = DateTime.Today; // One date time object is allocated and assigned to the stack. 
DoSomething(date); // this will result in a second date time object being allocated and assigned to the stack. 

private void DoSomething(DateTime date) 
{ 
    // do something with the date time object. 
} // As soon as we leave this method, the date time object is removed from the stack as it is now out of scope. 
+2

No es el GC el que libera las estructuras en la pila. Esos son simplemente "liberados" ajustando el puntero de la pila al final de una función, por lo que ahora están en la parte no utilizada de la pila. – CodesInChaos

+0

Buen punto, actualizaré mi respuesta para reflejar. –