¿Por qué no usar un código seguro no administrado en C #?

10

Hay una opción en C # para ejecutar código sin marcar. Por lo general, no se recomienda hacerlo, ya que el código administrado es mucho más seguro y supera muchos problemas.

Sin embargo, me pregunto, si está seguro de que su código no causará errores y sabe cómo manejar la memoria, ¿por qué (si le gusta el código rápido) siga los consejos generales?

Me pregunto esto desde que escribí un programa para una cámara de video, que requería una manipulación de mapa de bits extremadamente rápida. Hice algunos algoritmos gráficos rápidos yo mismo, y funcionan excelente en los mapas de bits utilizando código no administrado.

Ahora me pregunto en general, si está seguro de que no tiene pérdidas de memoria o riesgos de fallas, ¿por qué no usar el código no administrado con más frecuencia?

PD: mi experiencia: me metí en este mundo de programación y trabajo solo (lo hago durante unos años) y espero que esta pregunta de diseño de software no sea tan extraña. Realmente no tengo otras personas por ahí como un maestro para preguntar esas cosas.

usuario613326
fuente
8
unsafesignifica "saber lo que está haciendo y comparar los beneficios con los riesgos". He usado unsafeun puñado de veces, y siempre fue por algo muy específico relacionado con el rendimiento que podría ser tachado en su propio método. No lo uso como una técnica de programación general, ya que la mayoría de las veces el beneficio de rendimiento adicional no vale la pérdida de seguridad.
Robert Harvey
14
He escrito mucho código a lo largo de los años que a veces fallaba o tenía pérdidas de memoria, que estaba bastante seguro de que no tenía pérdidas de memoria o riesgos de fallas.
cuál es el
1
Aquí hay un buen unsafeejemplo de caso de uso: stackoverflow.com/q/11660127/102937
Robert Harvey
3
Supongo que su código de mapa de bits todavía tiene errores, pero simplemente no los detectó. E incluso si ese no es el caso, espere hasta que tenga que implementar algunos requisitos nuevos en el código existente.
Doc Brown,
1
Porque incluso cuando esté seguro de que su código no causará errores, sigue causando errores.
user253751

Respuestas:

27

Bueno, es principalmente un caso del viejo adagio

  • No optimizar
  • (solo para expertos) No optimice todavía

Pero en realidad puedo pensar en tres razones principales para evitar el código inseguro.

  1. Errores : la parte crítica de su pregunta es "si está seguro de que su código no causará errores". Bueno, ¿cómo puedes estar absolutamente seguro? ¿Utilizaste un probador con método formal que garantizara que tu código fuera correcto? Una cosa es cierta en la programación, y es que tendrá errores. Cuando se quita un seguro, permite que nuevos tipos de errores se cuelen. Cuando dejas que el recolector de basura se encargue de la memoria por ti, desaparecen muchos problemas.

  2. No siempre es tan rápido como crees : el otro punto es: dependiendo del problema, la ganancia puede no ser tan grande. Aunque parece que no puedo encontrarlos en este momento, recuerdo un estudio de Google que compara la velocidad de Java, Scala, Go y C ++. Una vez optimizado al suelo, por supuesto, C ++ fue mucho más rápido. Pero el algoritmo programado en la forma "idiomática" no fue realmente mucho más rápido. Idiomático en el sentido de que estaban usando estructura y modismos estándar (contenedor stl, sin bucle desenrollado, etc.). Microsoft hizo un experimento similar con C # y C ++. Raymond Chen, uno de los principales ingenieros de Microsoft, tuvo que escribir su propia implementación de std :: string para vencer a C #. (ver: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html) Por mucho menos esfuerzo, obtuvo un rendimiento bastante decente en el código administrado, por lo que a menudo no vale la pena.

  3. Reutilización : el código inseguro solo se puede usar en un entorno de plena confianza. Por ejemplo, en un servidor ASP.NET, generalmente no puede usar código inseguro, ya que sería bastante fácil introducir una vulnerabilidad por desbordamiento del búfer. Otro ejemplo sería clickonce. O si se accedió a su aplicación desde un recurso compartido de red. Entonces, si planea usar su código en una variedad de escenarios de implementación, el código inseguro está fuera del juego.

Básicamente: está mal visto porque puede introducir errores innecesarios, puede que no tenga ningún beneficio y reduce la reutilización de su código.

Pero si su escenario realmente lo requiere para el rendimiento (y tiene datos para demostrarlo), usted es un programador experimentado que sabe cómo manejar la memoria y su código se usará en un entorno controlado, entonces, seguro, hágalo.

Laurent Bourgault-Roy
fuente
4

En cierto modo, el código no administrado es una forma de pago: compra una ejecución más rápida con el esfuerzo de desarrollo adicional. De hecho, el código no administrado requiere más tiempo para desarrollarse, depurarse y mantenerse. Hacerlo exactamente bien es un desafío para la mayoría de los participantes. En cierto modo, esto es similar a la programación en ensamblaje: claro, puede exprimir más potencia de su CPU si escribe en ensamblaje * , pero "gasta" mucho más esfuerzo en esa ruta.

A veces, la diferencia en el tiempo de desarrollo es muy significativa: días en lugar de horas. Sin embargo, la diferencia en la velocidad de ejecución no es tan dramática. Es por eso que el desarrollo de código no administrado está reservado para situaciones similares a la que describió en su publicación: implementaciones localizadas y autónomas de algoritmos que consumen recursos, como el procesamiento de audio y video.

Esencialmente, la respuesta a su pregunta es similar a la respuesta de por qué no todos conducen Ferrari: es un automóvil mucho mejor, ¿verdad? (Des) afortunadamente, no todos pueden permitírselo.


* Los avances de las últimas décadas en la tecnología de optimización en compiladores han reducido esta brecha tanto que, sin embargo, ya no es una apuesta segura.

dasblinkenlight
fuente
0

Porque estar "seguro" sobre la corrección o cualquier otra restricción en el sentido matemático (es decir, tiene pruebas) es un problema muy difícil para los lenguajes imperativos. Los programas a menudo tienen un número tan alto de estados que no es posible verificarlos incluso al verificar cada estado posible. Y crear una prueba constructiva no es algo que pueda automatizar.

Entonces, la razón es que los seguros de que la ejecución administrada a menudo sobrestima la pequeña ganancia de rendimiento que obtendría con un código inseguro. Por supuesto, esto también depende del caso de uso específico.

Tamás Szelei
fuente
1
No creo que tenga nada que ver con la exactitud o la simplicidad a la razón ..
Jimmy Hoffa
Nadie habla de una prueba formal de corrección.
1
Estoy seguro de que su publicación pierde el punto, pero no formulo una prueba formal. Del mismo modo, puedo estar seguro de que mi programa es correcto (por ejemplo, después de extensas pruebas, depuración y uso prolongado en el mundo real sin que ocurran errores) sin probarlo de una vez por todas. Esta interpretación está mucho más cerca de lo que la mayoría de la gente quiere decir cuando dice "seguro que es correcto". Los métodos formales son una preocupación muy específica y están completamente fuera de consideración para la mayoría de los desarrolladores.
1
No veo tal pregunta. La pregunta, según lo leí, es acerca de por qué la escotilla de escape del mundo administrado no se debe / no se debe usar con más frecuencia (lo que implica que el incumplimiento del código administrado tiene sentido). En cualquier caso, si desea responder a esa pregunta (señalando la dureza de asegurar la corrección), puede hacerlo sin hablar de la seguridad absoluta y formal de la corrección. Su respuesta a partir de ahora gira únicamente en torno a pruebas completas y correctas de corrección de idiomas imperativos. Pero eso es excesivo, y creo que las pruebas sobre C # administrado son igualmente (o casi tan) difíciles.
1
@fish: puedo ver lo que estás diciendo. Existe una correlación entre algo difícil de probar y algo difícil de razonar. Si es difícil demostrar que es correcto, entonces probablemente sea difícil estar seguro de que es correcto.
Michael Shaw
0

En resumen, nada le impide hacer todo ese trabajo y administrar bits y tornillos de su programa en un entorno C ++. Como está bastante seguro de que puede administrar correctamente todos los aros y fugas de memoria sin recolector de basura, puede hacerlo en C ++ :)

Por el contrario, C # tiene ventajas al proporcionar un entorno de desarrollo seguro / administrado y fuertemente tipado para ejecutarse de manera segura en .NET Framework.

El posible inconveniente de la programación de código no administrado es el mayor tiempo de desarrollo, la asignación de tiempo para pruebas detalladas. Obviamente, obtendrá velocidad de procesamiento y más control sobre cómo se está ejecutando su software.

Por lo tanto, la opción de trabajar con código no administrado en .NET Framework a partir de 4.0 es una opción para casos extremos cuando está seguro de que podría generar ganancias por no usarlo ...

Yusubov
fuente
Ah, eso es interesante, ya veo que soy del mundo de los microcontroladores y allí generalmente se escribe c ++ decente, hay poco margen de error y un buen diseño de software es la clave
usuario613326