remarks example cref code c# performance unsafe

c# - example - Cierto rendimiento de código inseguro



params comments c# (5)

Entiendo que el código inseguro es más apropiado para acceder a cosas como la API de Windows y hacer conversiones de tipo inseguras que para escribir código más eficiente, pero me gustaría preguntarle si alguna vez ha notado alguna mejora significativa en el rendimiento en aplicaciones del mundo real al usarlo en comparación con el código de seguridad de c #.


Bueno, sugeriría leer esta entrada de blog: blogs de MSDN: Array Bounds Check Elimination en el CLR

Esto aclara cómo se realizan los controles de límites en C #. Además, las pruebas de Thomas Bratts me parecen inútiles (mirar el código) ya que el JIT elimina en su ''guardado'' lazos de los controles de límite de todos modos.


Como se indicó en otras publicaciones, puede usar código no seguro en contextos muy especializados para obtener una mejora significativa del rendimiento. Uno de esos escenarios es iterar sobre matrices de tipos de valor. Usar aritmética de punteros inseguros es mucho más rápido que usar el patrón habitual de for-loop / indexer.

struct Foo { int a = 1; int b = 2; int c = 0; } Foo[] fooArray = new Foo[100000]; fixed (Foo* foo = fooArray) // foo now points to the first element in the array... { var remaining = fooArray.length; while (remaining-- > 0) { foo->c = foo->a + foo->b; foo++; // foo now points to the next element in the array... } }

El principal beneficio aquí es que hemos eliminado completamente la comprobación del índice de matriz.

Si bien es muy eficaz, este tipo de código es difícil de manejar, puede ser bastante peligroso (inseguro) y rompe algunas pautas fundamentales (estructura mutable). Pero ciertamente hay escenarios donde esto es apropiado ...


Estoy usando un código inseguro para el código de manipulación de video. En dicho código, desea que se ejecute lo más rápido posible sin verificaciones internas de los valores, etc. Sin los atributos no seguros, no podría mantener el flujo de video a 30 fps o 60 fps. (Dependiendo de la cámara utilizada).

Pero debido a la velocidad es ampliamente utilizado por personas que codifican gráficos.


Un buen ejemplo es la manipulación de imágenes. La modificación de los píxeles mediante un puntero a sus bytes (que requiere un código no seguro) es bastante más rápida.

Ejemplo: http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx

Dicho esto, para la mayoría de los escenarios, la diferencia no sería tan notable. Entonces, antes de usar el código no seguro, haga un perfil de su aplicación para ver dónde están los cuellos de botella de rendimiento y pruebe si el código no seguro es realmente la solución para hacerlo más rápido.


Algunas mediciones de rendimiento

Los beneficios de rendimiento no son tan grandes como podría pensar.

Hice algunas mediciones de rendimiento del acceso al arreglo administrado normal frente a los punteros no seguros en C #.

Los resultados de una compilación se ejecutan fuera de Visual Studio 2010, .NET 4, utilizando una CPU Cualquiera | Lanzamiento basado en la siguiente especificación de PC: PC basado en x64, 1 procesador de cuatro núcleos. Intel64 Family 6 Model 23 Stepping 10 GenuineIntel ~ 2833 Mhz .

Linear array access 00:00:07.1053664 for Normal 00:00:07.1197401 for Unsafe *(p + i) Linear array access - with pointer increment 00:00:07.1174493 for Normal 00:00:10.0015947 for Unsafe (*p++) Random array access 00:00:42.5559436 for Normal 00:00:40.5632554 for Unsafe Random array access using Parallel.For(), with 4 processors 00:00:10.6896303 for Normal 00:00:10.1858376 for Unsafe

Tenga en cuenta que el idioma inseguro *(p++) realidad corrió más lento. Supongo que esto rompió una optimización del compilador que combinaba la variable de bucle y el acceso del puntero (generado por el compilador) en la versión segura.

Código fuente disponible en github .