Codificadores gestionados vs codificadores nativos

19

Soy codificador y tengo experiencia con código nativo y administrado. Comencé con Pascal y C, luego me mudé a C ++ y finalmente a C #.

Durante el último año más o menos, he estado codificando casi exclusivamente en C # y he perdido mucho de lo que solía ser natural cuando era un codificador de C ++.

Hace unas semanas, cuando me senté a escribir un código nativo de C ++, me encontré dando vueltas mientras me familiarizaba lentamente con las complejidades, peculiaridades e idiosincrasias de todo. Casi me da vergüenza decir que me había olvidado por completo de que pasar una matriz asignada dinámicamente a una función sin pasar también su tamaño significaría que la función receptora no tendría forma de saber cuánto dura la matriz.

Existen innumerables artículos y documentos que comparan y contrastan el código administrado con el no administrado. Todos sabemos que el código nativo, si está bien optimizado, puede ejecutarse significativamente más rápido y más ligero que el código administrado. Por otro lado, el código administrado tiene recolectores de basura y una optimización específica de la CPU y del sistema operativo en tiempo de ejecución que puede hacer que el código nativo se ejecute por su dinero.

Puramente desde una perspectiva técnica, no hay un ganador claro.

No hay duda de que el código administrado es un orden de magnitud más simple de codificar y comprender. Solo observe la diferencia en el número de líneas necesarias para construir una GUI simple en Win32 C ++ vs C #.

En mis días de codificación nativa, escribía principalmente simulaciones matemáticas que se ejecutaban en supercomputadoras. Tenían CLI feos y estaban centrados principalmente en algoritmos. Hoy en día escribo en C # y produzco hermosas aplicaciones GUI, pero me perdería si tuviera que hacer algo de un calibre similar en un idioma nativo. Incluso con un marco como QT, todavía tomaría el doble de tiempo producir algo en C ++ / QT que en C #.

Cada vez que veo a alguien que ha escrito una aplicación GUI a gran escala y con todas las funciones en C / C ++, no puedo evitar sentir asombro y un poco de celos.

Tengo curiosidad por cómo otros codificadores experimentados ven lenguajes administrados y no administrados. ¿Ves el código administrado como amateur-ish ? ¿Ves codificadores nativos como más hardcore ?


fuente

Respuestas:

26

Mi trabajo diario está actualmente en C ++, pero he programado en varios idiomas el tiempo suficiente para que apenas note la diferencia. Aquí están mis observaciones:

  • Muchas de las presuntas ineficiencias con otros lenguajes se vuelven a implementar con frecuencia por los programadores de C ++ como mejores prácticas. Agregamos suficientes verificaciones nulas, verificación de límites de matriz, verificación de tipos, validación de entrada, etc. para negar en gran medida cualquier ventaja de velocidad de ejecución obtenida por el lenguaje que no hace esas cosas automáticamente, al menos para el código que no requiere un procesamiento intensivo de datos.
  • Esa placa repetitiva adicional se convierte en un hábito arraigado después de un tiempo, por lo que realmente no se siente como un trabajo extra y sobresale como un pulgar dolorido cuando falta.
  • Cuando programo en un lenguaje "administrado" sigo pensando en la asignación de memoria, para asegurarme de no crear una pérdida de memoria. Puede que no esté poniendo un mensaje explícito delete, pero todavía estoy consciente en mi mente del punto en el que el recolector de basura lo considera elegible para su eliminación. Tuve más problemas para resolver problemas de poca memoria comenzando en Java que en C ++, probablemente porque en C ++ son mucho más difíciles de ignorar por mucho tiempo.
  • Lo mismo ocurre con la escritura dinámica. Todavía tengo que seguir en mi cabeza si un parámetro de función es una matriz, o un int, o una cadena. De hecho, requiere más esfuerzo mental porque el tipo no está claramente incluido allí para mí.
  • El estilo moderno de C ++ es muy diferente a la era anterior a C #. En lugar de cambiar el lenguaje, las personas "descubrieron" cómo usar las funciones existentes de C ++ de maneras únicas para evitar gran parte de la gestión de la memoria doméstica del pasado. Los patrones de diseño que liberan memoria automáticamente son muy comunes ahora.
  • Hasta donde yo sé, aunque es posible hacer aplicaciones GUI solo escribiendo código, los diseñadores gráficos como el diseñador QT son el método ampliamente preferido, con el código utilizado principalmente para controladores de eventos o personalización de tiempo de ejecución.
  • Los idiomas que no has usado mucho en un tiempo siempre se sienten un poco torpes, incluso si recuerdas la sintaxis. Si no escribo Python durante un año, hay muchas idiosincrasias que he olvidado, y se siente más incómodo que C ++ por un tiempo, aunque objetivamente la mayoría de las personas consideran que Python es el lenguaje "más fácil".

Con la combinación de todos esos factores, mi modelo mental se mantiene bastante consistente entre cuando programo en C ++ y otros lenguajes, y las diferencias se sienten principalmente sintácticas. Por supuesto, mucho de eso es el resultado de la capacitación, el hábito, los estándares de codificación y los patrones de diseño modernos en lugar de las características intrínsecas al lenguaje C ++ en sí, pero la comparación sigue vigente.

Supongo que lo que estoy tratando de decir es que, en mi experiencia, la capacitación del programador hace mucha más diferencia que el lenguaje que está usando.

Karl Bielefeldt
fuente
20

¿Ves el código administrado como amateur-ish? ¿Ves codificadores nativos como más hardcore?

No.

Veo las diferencias entre un ingeniero y un programador. El ingeniero incondicional siempre elegirá la pila de idioma / tecnología que sea apropiada para realizar el trabajo en el menor tiempo posible con un estándar de tiempo de ejecución aceptable.

Con la potencia del procesador en estos días, la frecuencia de la necesidad real de sacar el máximo provecho de una máquina mediante el uso de idiomas nativos de nivel inferior es cada vez menor. Por lo general, realmente no es un caso de negocios para ello. La productividad siempre superará una diferencia de unos milisegundos en el tiempo de ejecución.

Demian Brecht
fuente
1 pero hay que tener en cuenta que este es un efecto económico - si un ciclo de cálculo de costos de $ 1 millón a continuación, la optimización extrema descartaría - o que no había molestarse con las computadoras en todo ...
Gary Rowe
10
excepto que vemos un rendimiento general más bajo: Word6 funciona como la iluminación en un hardware moderno, Word2010 tarda un minuto en cargarse. ¡Hoy necesitamos ese hardware súper rápido para mantenerse al día con los programadores!
gbjbaanb
2
@ gbjbaanb: No importa qué programadores elijan, cualquier base de código lo suficientemente grande será lenta. IIRC, Word todavía está escrito en C ++ (y estaría dispuesto a apostar que una parte significativa de todo el código heredado de Word 6 todavía está allí).
Steven Evers
2
@gbjbaanb, Word 2010 no es una reescritura directa de Word 6 en .NET. Agrega muchas más funciones y tiene que manejar muchos más escenarios de uso. Es una aplicación mucho, mucho más grande que Word 6.
Mircea Chirea
6

Lamentablemente, Microsoft nos ha llevado a combinar "Código administrado" con las bibliotecas de clase C # /. Net.

Aquí hay dos cosas separadas y casi no relacionadas en juego.

  1. Geniales bibliotecas .Net.

  2. Código gestionado

C # ofrece ambos en un paquete ordenado, compatible y fácil de usar por un precio.

C ++ tiene numerosas bibliotecas geniales que hacen casi todo lo que hace .Net. En lugar de culpar al código "nativo de C ++" por tener más "complejidades, peculiaridades e idiosincrasias" que el código C # /. Net, podría buscar mejores bibliotecas de C ++.

Las mejores bibliotecas también le permiten escribir un buen código C ++.

Cada vez que veo a alguien que ha escrito una aplicación GUI a gran escala y con todas las funciones en C / C ++, no puedo evitar sentir una sensación de asombro y una pizca de celos.

Mala política En su lugar, debe averiguar qué bibliotecas de definiciones de clase utilizaron. Usted también podría usar esas bibliotecas.

Se trata de las herramientas. Sin herramientas, solo somos animales en pantalones.

"Native C ++" no significa que deba tirar todas sus herramientas. Significa que tienes que encontrar buenas herramientas. Microsoft ya no lo ayuda, por lo que debe dedicar tiempo a encontrar la combinación correcta de herramientas.

S.Lott
fuente
+1 para el "ve a descubrir qué están usando", pero, francamente, creo que esto no es muy bueno para los animales que usan herramientas, o animales que ocasionalmente usan pantalones.
Ian Pugsley
@ Ian Pugsley: Los animales que usan pantalones pero no usan herramientas probablemente estén de acuerdo con su condición de animales. Pero tienes razón en que los animales que usan herramientas sin pantalones podrían enojarse. Mi esposa, por ejemplo, prefiere no usar pantalones y usa herramientas. Quizás ella no lea esta pregunta.
S.Lott
Solo podemos esperar (y apostar por las posibilidades bastante altas). Todo lo que digo es que no menospreciaré a un animal lo suficientemente inteligente como para ponerme un par de pantalones ... por si acaso.
Ian Pugsley
Sí, a diferencia de la biblioteca estándar de C #, C ++ es antigua y carece de necesidades modernas (GUI, interfaz de red genial, etc.).
Moshe Revah
Microsoft lo está ayudando una vez más con C ++ en Windows 8 (toda la superficie de desarrollo de Windows 8 es código nativo, y C ++ es un ciudadano de primera clase junto con C # y JavaScript): msdn.microsoft.com/en-us/library/windows/ aplicaciones / ...
Zach
5

El problema aquí no se trata de programación hardcore o algo así, se trata de control. El hecho es que C # ofrece productividad a un costo de control. Si está escribiendo un programa que necesita una gran cantidad de control (esta memoria está desasignada exactamente ahora), entonces no tiene más remedio que usar C ++. Si necesita hacerlo rápidamente, es posible que deba usar C #. El problema es que las bibliotecas de soporte para C # son mucho mejores y más recientes que las proporcionadas para C ++. Por ejemplo, MFC es muy, muy antiguo y se sabe que sus prácticas son terribles, principalmente se escribió mucho antes de la Estandarización. Si Microsoft se esforzó por proporcionar nuevas bibliotecas de C ++, por ejemplo, consulte la nueva PPL en Visual Studio 2010, entonces, curiosamente, esa tarea se vuelve fácil en C ++. Y creo que están migrando de esa manera,

Por otro lado, el código administrado tiene recolectores de basura y una optimización específica de la CPU y del sistema operativo en tiempo de ejecución que puede hacer que el código nativo se ejecute por su dinero.

He escuchado a muchos defensores del lenguaje administrado decir esto, pero casi nunca he visto que sea verdad. El hecho es que las nuevas instrucciones de CPU disponibles en las CPU más nuevas simplemente no ofrecen tanta ventaja a menos que esté haciendo matemáticas muy exigentes, en cuyo caso no puede permitirse la sobrecarga de tener que compilarlo o interpretarlo durante la ejecución -time y podrías usar el compilador C ++ de Intel para usar lo último y lo mejor en SSE de todos modos. El alcance de las optimizaciones del compilador de C ++ es enorme en comparación con lo que puede hacer el JIT, porque el JIT tiene que ejecutarse en una fracción del tiempo mientras el programa se está ejecutando, mientras que los compiladores de C ++ son bastante legendarios por tomarse su dulce tiempo para compilar.

La recolección de basura no es una especie de cosa mágicamente grandiosa o algo así, es una elección de algoritmo. ¿Es apropiado para todas las situaciones? No, por mucho, mire el desorden IDisposable en C # y cómo Java ni siquiera se molestó en tratar con ese problema, mientras que los destructores de C ++ cerrarán sus archivos y liberarán su memoria y cerrarán sus sockets, etc. etc. GC es ideal para algunos programas , y no para otros.

DeadMG
fuente
Hay más diferencias entre los procesadores que SIMD, aunque su compilador C ++ probablemente tenga en cuenta la tubería tanto como su JIT.
Peter Taylor
Un entorno de tiempo de ejecución en el que es posible examinar el estado del sistema e identificar todas las referencias de objetos no anclados a las que se pueda acceder puede amortizar muchos costos relacionados con GC de formas que no son posibles en C ++. En Java o C #, dada String foo,bar;la instrucción, foo=bar;se ejecutarán dos instrucciones: una carga de registro y un almacén de registros. Tiempo de ejecución constante independientemente de la longitud de la cadena. ¿Puede C ++ acercarse?
supercat
2

En mi opinión, C / C ++ nativo, en comparación con C #, parece un ensamblador para C / C ++. Otra capa compleja de abstracción (no exactamente verdadera, pero digamos que sí), como siempre, le brinda un desarrollo más fácil, pero una reducción en la velocidad y un uso excesivo de memoria. Entonces, según lo veo, se divide en diferentes categorías, creando así nuevos subtipos de programadores.

Por cierto, por su nivel de abstracción, C # es increíblemente rápido, Microsoft hizo un excelente trabajo.

Petr Abdulin
fuente
2

Hay programadores aficionados, no lenguajes aficionados. Idiomas que tienen todos (bueno, la mayoría de ellos al menos) su propósito.

Actualmente estoy trabajando en un motor de cálculo de seguros utilizado para probar el sistema de producción. El sistema de producción se ha realizado en C, nuestro motor está hecho en Java y, desde hace más tiempo, superamos al motor en C, siendo al mismo tiempo mucho más productivos. No porque Java per se sea más rápido que C, es lo suficientemente rápido y nuestros algoritmos son mejores, los hemos implementado más fácilmente, podríamos probar y refactorizar nuestro código más rápido y mejor.

También escribí un código de prueba para comparar los resultados de cálculo con el contenido de la base de datos de producción: no en C, no en Java sino en Ruby. Nuevamente, es lo suficientemente rápido y necesita mucho menos código, por lo que es más fácil de implementar, más fácil de probar, más fácil de expandir.

Y no me siento aficionado sin importar el idioma que use, me siento así solo si hago un error estúpido que no debería haber sucedido.

Tomasz Stanczak
fuente
1

El año pasado, la empresa en la que trabajo realizó ingeniería inversa de un código CRC de comunicaciones por fuerza bruta (finalmente lo obtuvimos). 3 Los desarrolladores tenían cada uno su propia versión, Borland C, C # .Net 2008, VB6. VB6 fue obviamente lento, Borland C fue rápido, pero C # .net simplemente lo azotó 12 veces la velocidad. No era lo que esperábamos en absoluto.

Craig White
fuente
1
¿Están usando el mismo algoritmo paso a paso? Podrían estar calculando la misma salida, pero los pasos matemáticos elementales utilizados para llegar a la salida pueden ser diferentes, y el rendimiento está determinado por el recuento bruto de los pasos elementales, que a su vez se determina a partir de cómo se descompone la "fórmula" en ellos.
rwong
Un compilador de C mayor no puede estar utilizando las últimas instrucciones del procesador (es decir, SSE2 y posteriores)
GrandmasterB
1
Los tres idiomas compilan en código nativo optimizado (VB6 / C ++ durante la compilación, .NET durante JIT). Por lo tanto, probablemente esté midiendo las diferencias entre sus programadores en lugar de entre los lenguajes de programación.
nikie
@nikie JIT! = compilación. Y la calidad de los compiladores es diferente. He visto exactamente el mismo algoritmo ejecutarse mucho más rápido cuando se escribe en C ++ (sin llamadas a la API, solo referencias de matriz, bucles y aritmética simple) que en Java, a pesar de todo lo que se habla sobre JIT.
quant_dev
1
@quant_dev: En mi experiencia no hay una bala de plata ;-) Mi experiencia con .NET JIT es que la diferencia entre JIT y MSVC ++ es muy pequeña. Dudo mucho 12x de cualquier manera para el mismo código.
nikie
1

Depende de una combinación de cosas, pero básicamente, todo lo demás es igual, sí, el código nativo es más "duro" que el código administrado.

Sin embargo, supongo que eso suele ser algo malo para una aplicación comercial normal, porque significa que el desarrollador promedio debe poner más energía mental en los aspectos no comerciales de su código.

John Bickers
fuente
1

Mi programa es lo que podría describirse mejor como C ++ como Java. Mi opinión es que puedes lograr la misma programación de bajo nivel en Java, pero es mucho más difícil que la programación de bajo nivel en C ++. Sin embargo, generalmente necesita esta programación de bajo nivel en una pequeña fracción de su código y donde no se requiere un lenguaje administrado es más productivo.

Peter Lawrey
fuente
1

Los desarrolladores nativos generalmente obtienen la reputación de ser más duros porque se sienten más duros y actúan de esa manera. Los desarrolladores nativos están capacitados en un sistema que no tolera ningún error porque inevitablemente provocan bloqueos duros o pérdidas de memoria ilimitadas. En particular, .NET permite hacks perezosos como poner try / catch alrededor de todo, evitando que el desarrollador piense que tiene que entender el problema central ("a veces, solo arroja InvalidOperationException. No puedo explicarlo, vamos a atrapar todo. Esto el código es crítico "). Esto no es en absoluto en blanco y negro, pero mis observaciones han crecido en el mundo no administrado y ahora están trabajando en código administrado a tiempo completo.

Además, los desarrolladores administrados también tienden a tener acceso a BCL mucho más limpios y organizados. Esto a menudo los alienta a explorar lo que realmente sucede debajo de las sábanas. Es cierto que se puede decir lo mismo de, por ejemplo, STL o Boost, pero la biblioteca de clases .NET a menudo es lo suficientemente buena como para hacernos intelectualmente perezosos a veces.

Dicho esto, escribir un buen programa administrable que se pueda enviar requiere mucho trabajo. Eso significa hacer perfiles de memoria y CPU, pruebas unitarias y análisis de código de manera similar a como lo hacen los desarrolladores no administrados. Los desarrolladores no administrados tienden a entender esto, y los desarrolladores administrados tienden a incluir a más de los que no lo hacen.

De nuevo, no en blanco y negro. Hay muchos desarrolladores no administrados intelectualmente perezosos y desarrolladores administrados hardcore. Ninguno de los dos es, por definición, más elitista que el otro.

Kevin Hsu
fuente
0

¿Ves el código administrado como amateur-ish? ¿Ves codificadores nativos como más hardcore?

Hay una brecha entre los dos mundos, y no puedo ver por qué: los sistemas administrados están escritos en algún lugar en código nativo (como final, todo se ejecuta "en conjunto"). Lo que quiero ver (aún en mi vida) es un sistema de construcción de aplicaciones, donde toda la subtarea de la aplicación se escribirá en el tipo de idioma correcto.

ern0
fuente
Un sistema de construcción de aplicaciones como usted describe es solo otro lenguaje de programación (y con suerte mejor).
David Thornley
No estoy familiarizado con .NET, pero AFAIK es un sistema de lenguaje mixto, que tiene un formato ejecutable común ejecutado por una VM y una biblioteca masiva que se puede usar con cualquier lenguaje .NET. Un mismo sistema sería bueno en el mundo nativo / compilado. Independiente de la plataforma, por supuesto.
ern0
0

El código nativo se hizo más fácil desde que se lanzó Go . Me resulta más fácil leer y escribir que Java y C #. Aunque la programación GUI con Go, a partir de ahora, no es muy agradable (eché un vistazo rápido a las opciones).
Trate de no juzgarlo por su falta de gran comunidad y variedad de bibliotecas en comparación con C # (por ejemplo), porque todavía se considera nuevo.

Moshe Revah
fuente