Pregunta

¿Alguien ha utilizado realmente stackalloc durante la programación en C #? Soy consciente de lo que se hace, pero la única vez que aparece en mi código es por accidente, porque Intellisense sugiere que cuando comienzo a escribir static, por ejemplo.

A pesar de que no está relacionado con los escenarios de uso de stackalloc, que realmente hacen una cantidad considerable de interoperabilidad legado en mis aplicaciones, por lo que de vez en cuando pude recurrir al uso de código unsafe. Pero, sin embargo, por lo general encuentran maneras de evitar unsafe por completo.

Y puesto que el tamaño de pila para una única secuencia en .Net es ~ 1 Mb (corríjanme si me equivoco), estoy aún más reservado el uso de stackalloc.

¿Hay algunos casos prácticos en los que uno podría decir: "esto es exactamente la cantidad correcta de datos y el procesamiento para mí ir inseguro y uso stackalloc"

¿Fue útil?

Solución

La única razón para usar stackalloc es el rendimiento (ya sea por cálculos o de interoperabilidad). Mediante el uso de stackalloc lugar de una matriz montón asignado, se crea menos presión GC (GC necesita correr menos), que no es necesario para fijar las matrices de abajo, que es más rápido para asignar a una matriz montón, una que se libera automáticamente en salida método (montón asignado arrays solamente se desasignan cuando GC se ejecuta). También mediante el uso de stackalloc en lugar de un asignador nativa (como malloc o el equivalente .Net) usted también gana velocidad y cancelación de asignación automática a la salida ámbito de aplicación.

En cuanto al rendimiento, si se utiliza stackalloc que aumenta enormemente la posibilidad de aciertos de caché en la CPU debido a la localidad de datos.

Otros consejos

he utilizado stackalloc asignar buffers para [cerca] trabajo en tiempo real DSP. Fue un caso muy específico donde el rendimiento necesario para ser lo más consistente posible. Tenga en cuenta que hay una diferencia entre la consistencia y el rendimiento global - en este caso, que no estaba preocupado con asignaciones del montón es demasiado lenta, simplemente con el no determinismo de la recolección de basura en ese punto en el programa. Yo no lo usaría en el 99% de los casos.

stackalloc sólo es relevante para el código no seguro. Para el código administrado no puede decidir dónde asignar los datos. Los tipos de valor 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). Tipos de referencia se asignan en el montón.

El tamaño de pila predeterminado para una aplicación .NET con sabor de vainilla es de 1 MB, pero puede cambiar esto en la cabecera PE. Si vas a empezar las discusiones de manera explícita, también puede establecer un tamaño diferente a través de la sobrecarga del constructor. Para las aplicaciones ASP.NET el tamaño de pila predeterminado es solamente de 256 K, que es algo a tener en cuenta si el cambio entre los dos entornos.

stackalloc inicialización de vanos. En las versiones anteriores de C #, el resultado de stackalloc sólo podía ser almacenado en una variable local puntero. A partir de C # 7.2, stackalloc ahora se puede utilizar como parte de una expresión y pueden dirigirse a un lapso, y que se puede hacer sin necesidad de utilizar la palabra clave inseguro. Por lo tanto, en lugar de escribir

Span<byte> bytes;
unsafe
{
  byte* tmp = stackalloc byte[length];
  bytes = new Span<byte>(tmp, length);
}

Puede escribir simplemente:

Span<byte> bytes = stackalloc byte[length];

Esto también es muy útil en situaciones donde se necesita un poco de espacio cero para realizar una operación, pero desea evitar la asignación de memoria del montón de tamaños relativamente pequeños

Span<byte> bytes = length <= 128 ? stackalloc byte[length] : new byte[length];
... // Code that operates on the Span<byte>

Fuente: C # - Todo sobre Span: Exploring un nuevo .NET Mainstay

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top