2009-04-24 23 views
85

¿Alguna vez alguien realmente ha usado stackalloc mientras programaba en C#? Soy consciente de lo que hace, pero la única vez que aparece en mi código es por accidente, porque Intellisense lo sugiere cuando empiezo a escribir static, por ejemplo.Uso práctico de la palabra clave `stackalloc`

Aunque no está relacionado con los escenarios de uso de stackalloc, de hecho hago una considerable cantidad de interoperabilidad heredada en mis aplicaciones, por lo que de vez en cuando podría recurrir al uso del código unsafe. Pero, sin embargo, suelo encontrar maneras de evitar unsafe por completo.

Y como el tamaño de la pila para un solo hilo en .Net es ~ 1Mb (corríjanme si me equivoco), estoy aún más reservado de usar stackalloc.

¿Hay algunos casos prácticos donde uno podría decir: "esta es exactamente la cantidad correcta de datos y procesamiento para que no sea seguro y use stackalloc"?

+2

acaba de notar que 'System.Numbers' lo usa mucho https://referencesource.microsoft.com/#mscorlib/system/number.cs,86404b606ba1649f – Slai

Respuesta

90

La única razón para usar stackalloc es el rendimiento (ya sea para cálculos o interoperabilidad). Al usar stackalloc en lugar de una matriz asignada de montón, se crea menos presión de GC (la GC necesita ejecutarse menos), no es necesario fijar las matrices, es más rápida de asignar que una matriz de montón, y se libera automáticamente en método de salida (las matrices asignadas en el montón solo se desasignan cuando se ejecuta GC). Además, al usar stackalloc en lugar de un asignador nativo (como malloc o el equivalente de .Net), también gana velocidad y desasignación automática en la salida del alcance.

En cuanto al rendimiento, si utiliza stackalloc, aumenta enormemente la probabilidad de que la caché acceda a la CPU debido a la localidad de los datos.

+19

Localidad de datos, buen punto! Eso es lo que rara vez logrará la memoria administrada cuando desee asignar varias estructuras o matrices. ¡Gracias! – Groo

+16

Las asignaciones de montón suelen ser más rápidas para los objetos administrados que para las no administradas porque no hay una lista libre para recorrer; el CLR simplemente incrementa el puntero del montón. En cuanto a la localidad, es más probable que las asignaciones secuenciales terminen colocadas para procesos administrados de larga ejecución debido a la compactación en pila. –

20

stackalloc solo es relevante para códigos inseguros. Para el código administrado, no puede decidir dónde asignar los datos. Los tipos de valores se asignan en la pila por defecto (a menos que sean parte de un tipo de referencia, en cuyo caso se asignan en el montón). Los tipos de referencia se asignan en el montón.

El tamaño de pila predeterminado para una aplicación simple .NET es de 1 MB, pero puede cambiar esto en el encabezado PE. Si está iniciando subprocesos explícitamente, también puede establecer un tamaño diferente a través de la sobrecarga del constructor. Para las aplicaciones ASP.NET, el tamaño predeterminado de la pila es de solo 256K, que es algo a tener en cuenta si cambia entre los dos entornos.

+0

¿Es posible cambiar el tamaño de pila predeterminado de Visual Studio? – configurator

+0

@configurator: Hasta donde sé, no. –

27

He utilizado stackalloc para asignar memorias intermedias para el trabajo DSP en tiempo real [casi]. Fue un caso muy específico en el que el rendimiento debía ser lo más constante posible. Tenga en cuenta que existe una diferencia entre la consistencia y el rendimiento general; en este caso, no me preocupaba que las asignaciones de heap fueran demasiado lentas, solo con el no determinismo de la recolección de basura en ese punto del programa. No lo usaría en el 99% de los casos.