differences - c++ vs c# vs c
Rendimiento C++ vs. Java/C# (30)
Mi entendimiento es que C / C ++ produce código nativo para ejecutarse en una arquitectura de máquina particular. Por el contrario, los lenguajes como Java y C # se ejecutan sobre una máquina virtual que abstrae la arquitectura nativa. Lógicamente, parece imposible que Java o C # coincidan con la velocidad de C ++ debido a este paso intermedio, sin embargo, me han dicho que los últimos compiladores ("hot spot") pueden alcanzar esta velocidad o incluso superarla.
Quizás esta sea más una pregunta de compilación que una cuestión de idioma, pero ¿alguien puede explicar en un lenguaje sencillo cómo es posible que uno de estos lenguajes de máquina virtual funcione mejor que un idioma nativo?
Aquí hay algunas buenas respuestas sobre la pregunta específica que hizo. Me gustaría dar un paso atrás y mirar la imagen más grande.
Tenga en cuenta que la percepción de su usuario de la velocidad del software que escribe se ve afectada por muchos otros factores, además de por la optimización del Codegen. Aquí hay unos ejemplos:
La administración manual de la memoria es difícil de realizar correctamente (sin pérdidas), y aún más difícil de realizar con eficacia (memoria libre poco después de que haya terminado con ella). Usar un GC es, en general, más probable que produzca un programa que maneje bien la memoria. ¿Estás dispuesto a trabajar mucho y retrasar la entrega de tu software, en un intento de superar al GC?
Mi C # es más fácil de leer y entender que mi C ++. También tengo más formas de convencerme de que mi código C # está funcionando correctamente. Eso significa que puedo optimizar mis algoritmos con menos riesgo de introducir errores (y a los usuarios no les gusta el software que se bloquea, ¡incluso si lo hace rápidamente!)
Puedo crear mi software más rápido en C # que en C ++. Eso libera tiempo para trabajar en el rendimiento y aún entregar mi software a tiempo.
Es más fácil escribir una IU buena en C # que en C ++, por lo que es más probable que pueda llevar el trabajo a segundo plano mientras la IU sigue siendo receptiva, o para proporcionar progreso o escuchar UI cuando el programa tiene que bloquearse por un tiempo. Esto no hace que todo sea más rápido, pero hace que los usuarios estén más contentos de esperar.
Todo lo que dije sobre C # probablemente sea cierto para Java, simplemente no tengo la experiencia para decirlo con certeza.
El código ejecutable producido a partir de un compilador Java o C # no se interpreta: se compila con el código nativo "just in time" (JIT). Entonces, el primer código de tiempo en un programa Java / C # se encuentra durante la ejecución, hay una sobrecarga ya que el "compilador de tiempo de ejecución" (también conocido como compilador JIT) convierte el código de bytes (Java) o IL (C #) en instrucciones nativas. Sin embargo, la próxima vez que se encuentre el código mientras la aplicación aún se está ejecutando, el código nativo se ejecutará inmediatamente. Esto explica cómo algunos programas Java / C # parecen ser lentos inicialmente, pero luego funcionan mejor cuanto más tiempo corren. Un buen ejemplo es un sitio web ASP.Net. La primera vez que se accede al sitio web, puede ser un poco más lento ya que el compilador JIT compila el código C # al código nativo. Los accesos posteriores resultan en un sitio web mucho más rápido: el lado del servidor y el lado del caché.
Generalmente, el algoritmo de su programa será mucho más importante para la velocidad de su aplicación que el idioma . Puede implementar un algoritmo pobre en cualquier idioma, incluido C ++. Con esto en mente, generalmente podrá escribir código en las corridas más rápido en un lenguaje que le ayude a implementar un algoritmo más eficiente.
Los lenguajes de alto nivel funcionan muy bien al proporcionar un acceso más fácil a muchas estructuras de datos preconstruidas eficientes y prácticas alentadoras que lo ayudarán a evitar el código ineficiente. Por supuesto, a veces también pueden hacer que sea fácil escribir muchos códigos realmente lentos, por lo que aún debe conocer su plataforma.
Además, C ++ se está poniendo al día con las características "nuevas" (tenga en cuenta las comillas) como los contenedores STL, punteros automáticos, etc. - consulte la biblioteca de impulso, por ejemplo. Y a veces puede encontrar que la forma más rápida de realizar una tarea requiere una técnica como la aritmética de puntero que está prohibida en un lenguaje de nivel superior, aunque normalmente le permiten llamar a una biblioteca escrita en un idioma que puede implementarla como desee. .
Lo principal es conocer el idioma que está utilizando, su API asociada, qué puede hacer y cuáles son sus limitaciones.
JIT (Just In Time Compiling) puede ser increíblemente rápido porque optimiza para la plataforma objetivo.
Esto significa que puede aprovechar cualquier truco de compilación que su CPU pueda admitir, independientemente de la CPU en la que el desarrollador escribió el código.
El concepto básico de .NET JIT funciona así (muy simplificado):
Llamar a un método por primera vez:
- Tu código de programa llama a un método Foo ()
- El CLR mira el tipo que implementa Foo () y obtiene los metadatos asociados a él
- A partir de los metadatos, el CLR sabe en qué dirección de memoria se almacena el IL (código de bytes intermedio).
- El CLR asigna un bloque de memoria y llama al JIT.
- El JIT compila el IL en el código nativo, lo coloca en la memoria asignada y luego cambia el puntero de función en los metadatos de tipo Foo () para que apunten a este código nativo.
- El código nativo está en ejecución.
Llamar a un método por segunda vez:
- Tu código de programa llama a un método Foo ()
- El CLR mira el tipo que implementa Foo () y encuentra el puntero a la función en los metadatos.
- El código nativo en esta ubicación de memoria se ejecutó.
Como puede ver, la segunda vez, es prácticamente el mismo proceso que C ++, excepto con la ventaja de las optimizaciones en tiempo real.
Dicho esto, todavía hay otros problemas generales que ralentizan un lenguaje administrado, pero el JIT ayuda mucho.
No estoy seguro de la frecuencia con la que descubrirá que el código Java se ejecutará más rápido que C ++, incluso con Hotspot, pero me inclinaré a explicar cómo podría suceder.
Piense en el código compilado de Java como lenguaje de máquina interpretado para JVM. Cuando el procesador de Hotspot advierte que ciertas piezas del código compilado van a ser utilizadas muchas veces, realiza una optimización en el código de la máquina. Dado que el ensamblaje de ajuste manual es casi siempre más rápido que el código compilado en C ++, está bien suponer que el código de máquina sintonizado programáticamente no va a ser tan malo.
Entonces, para el código altamente repetitivo, pude ver dónde sería posible que Hotspot JVM ejecutara Java más rápido que C ++ ... hasta que la recolección de basura entre en juego. :)
Si usted es un programador de Java / C # que está aprendiendo C ++, tendrá la tentación de seguir pensando en términos de Java / C # y traducir textualmente a la sintaxis de C ++. En ese caso, solo obtendrá los beneficios antes mencionados de código nativo vs. interpretado / JIT. Para obtener la mayor ganancia de rendimiento en C ++ frente a Java / C #, debe aprender a pensar en C ++ y diseñar código específicamente para explotar las fortalezas de C ++.
Parafraseando a Edsger Dijkstra : [tu primer idioma] mutila la mente más allá de la recuperación.
Parafraseando a Jeff Atwood : puedes escribir [tu primer idioma] en cualquier idioma nuevo.
En algunos casos, el código administrado en realidad puede ser más rápido que el código nativo. Por ejemplo, "marca-y-barrido" algoritmos de recolección de basura permiten entornos como el JRE o CLR para liberar un gran número de corta duración (normalmente) objetos en una sola pasada, donde son liberados mayoría ++ objetos montón C / C uno franco un momento.
De Wikipedia :
Para muchos propósitos prácticos, la asignación / desasignación-algoritmos implementados en idiomas intensivos de basura recogida en realidad puede ser más rápido que sus equivalentes utilizando asignación del montón manual. Una razón importante de esto es que el recolector de basura permite que el sistema de tiempo de ejecución para amortizar las operaciones de asignación y desasignación de una manera potencialmente ventajosa.
Dicho esto, he escrito un montón de C # y una gran cantidad de C ++, y me he encontrado una gran cantidad de puntos de referencia. En mi experiencia, C ++ es mucho más rápido que C #, de dos maneras: (1) si usted toma un código que usted ha escrito en C #, portarlo a C ++ el código nativo tiende a ser más rápido. ¿Cuanto más rápido? Bueno, varía mucho, pero no es raro ver a una mejora de la velocidad 100%. (2) En algunos casos, la recolección de basura puede masivamente frenar una aplicación administrada. El .NET CLR hace un trabajo horrible con grandes montones (por ejemplo,> 2 GB), y puede llegar a gastar mucho tiempo en GC - incluso en las aplicaciones que tienen pocos - o incluso sin - objetos de la vida intermedia se extiende.
Por supuesto, en la mayoría de los casos que he encounted, lograron lenguas son lo suficientemente rápido, por un tiro largo, y el mantenimiento y solución de compromiso que codifica para la capacidad de C ++ no es simplemente una buena.
Es sólo ocurriría si el intérprete de Java está produciendo código de máquina que en realidad está mejor optimizado que el código máquina de su compilador genera el código C ++ que está escribiendo, hasta el punto en el código C ++ es más lento que el de Java y los costes de interpretación.
Sin embargo, las probabilidades de que ocurra son en realidad bastante bajo - a no ser que tal vez Java tiene una biblioteca muy bien escrito, y tiene su propia biblioteca mal escrito en C ++.
La compilación para optimizaciones de CPU específicas suele estar sobrevalorada. Simplemente tome un programa en C ++ y compile con optimización para pentium PRO y ejecute en un pentium 4. Luego recompile con optimize para pentium 4. Pasé largas tardes haciéndolo con varios programas. Resultados generales? Por lo general, menos del 2-3% de aumento en el rendimiento. Entonces las ventajas teóricas de JIT son casi nulas. La mayoría de las diferencias de rendimiento solo se pueden observar cuando se utilizan funciones de procesamiento de datos escalares, algo que eventualmente necesitará un ajuste fino manual para lograr el máximo rendimiento de todos modos. Las optimizaciones de ese tipo son lentas y costosas de realizar, por lo que a veces no son adecuadas para JIT.
En el mundo real y la aplicación real, C ++ sigue siendo generalmente más rápido que Java, principalmente debido a la menor huella de memoria que resulta en un mejor rendimiento de la memoria caché.
Pero para usar toda la capacidad de C ++ usted, el desarrollador debe trabajar duro. Puedes lograr resultados superiores, pero debes usar tu cerebro para eso. C ++ es un lenguaje que decidió presentarte más herramientas, cobrando el precio que debes aprender para poder usar bien el lenguaje.
He aquí un punto de referencia interesante http://zi.fi/shootout/
Yo tampoco lo sé ... mis programas Java siempre son lentos. :-) Sin embargo, nunca me había dado cuenta de que los programas de C # son particularmente lentos.
En realidad de Sun HotSpot JVM utiliza "modo mixto" ejecución. Se interpreta el código de bytes del método hasta que se determina (generalmente a través de un contador de algún tipo) que va a ser ejecutado una gran cantidad de un bloque de código (método, el lazo, el bloque try-catch, etc.), entonces JIT compila. El tiempo necesario para JIT compila un método a menudo toma más tiempo que si el método se interpretara si se trata de un método rara vez se ejecute. El rendimiento es generalmente más alta para "modo mixto", porque la JVM no pierde el código de JITing tiempo que es rara vez, o nunca, correr. C # y .NET no hacen esto. NET JIT todo lo que, muchas veces, una pérdida de tiempo.
En realidad, C # en realidad no se ejecuta en una máquina virtual de Java, como lo hace. IL se compila en lenguaje ensamblador, que es totalmente código nativo y funciona a la misma velocidad que el código nativo. Usted puede pre-JIT una aplicación .NET que elimina por completo el costo JIT y luego está ejecutando código nativo en su totalidad.
La desaceleración con .NET no vendrá porque el código .NET es más lento, pero debido a que hace mucho más detrás de las escenas para hacer las cosas como basura recoger, verificar referencias, tienda de marcos de pila completos, etc. Esto puede ser muy potente y útil cuando se la creación de aplicaciones, sino que también tiene un costo. Tenga en cuenta que usted podría hacer todas estas cosas en un programa en C ++, así (gran parte de la funcionalidad básica de .NET es en realidad código .NET que se puede ver en el rotor). Sin embargo, si la mano escribió la misma funcionalidad que probablemente acabaría con un programa mucho más lento ya que el tiempo de ejecución de .NET ha sido optimizado y afinado.
Dicho esto, uno de los puntos fuertes de código administrado es que puede ser totalmente verificable, es decir. se puede verificar que el código nunca va a acceder a la memoria de otro proceso o hacer cosas unsage antes de ejecutarlo. Microsoft tiene un prototipo de investigación de un sistema operativo completamente gestionado que ha mostrado sorprendentemente que un entorno gestionado 100% en realidad puede llevar a cabo mucho más rápido que cualquier sistema operativo moderno mediante el aprovechamiento de esta verificación para desactivar las funciones de seguridad que ya no se necesitan los programas administrados (estamos hablando como 10 veces más en algunos casos). Radio SE tiene un gran episodio hablando de este proyecto.
Una de las optimizaciones de JIT más significativas es el método en línea. Java puede incluso incluir métodos virtuales en línea si puede garantizar la corrección del tiempo de ejecución. Por lo general, este tipo de optimización no puede ser realizado por compiladores estáticos estándar porque necesita un análisis completo del programa, lo cual es difícil debido a la compilación separada (en contraste, JIT tiene todo el programa disponible). La alineación del método mejora otras optimizaciones, dando bloques de código más grandes para optimizar.
La asignación de memoria estándar en Java / C # también es más rápida, y la desasignación (GC) no es mucho más lenta, pero solo menos determinista.
Aquí hay otro punto de referencia interesante, que puedes probar en tu propia computadora.
Compara ASM, VC ++, C #, Silverlight, applet de Java, Javascript, Flash (AS3)
Demo de la velocidad del complemento Roozz
Tenga en cuenta que la velocidad de javascript varía mucho según el navegador que la ejecute. Lo mismo es cierto para Flash y Silverlight porque estos complementos se ejecutan en el mismo proceso que el navegador de alojamiento. Pero el complemento de Roozz ejecuta archivos .exe estándar, que se ejecutan en su propio proceso, por lo que el navegador de alojamiento no influye en la velocidad.
En la parte superior de lo que algunos otros han dicho, desde mi entendimiento .NET y Java son mejores en la asignación de memoria. Por ejemplo, se puede compactar la memoria a medida que se fragmenta mientras que C ++ no puede (de forma nativa, pero se puede si se está utilizando un recolector de basura inteligente).
Debe definir "realizar mejor que ...". Bueno, lo sé, preguntaste sobre la velocidad, pero no es todo lo que cuenta.
- ¿Las máquinas virtuales realizan más sobrecarga de tiempo de ejecución? ¡Sí!
- ¿Comen más memoria de trabajo? ¡Sí!
- ¿Tienen costos de inicio más altos (inicialización del tiempo de ejecución y compilador JIT)? ¡Sí!
- ¿Requieren una gran biblioteca instalada? ¡Sí!
Y así sucesivamente, es parcial, sí;)
Con C # y Java, pagas un precio por lo que obtienes (codificación más rápida, administración automática de memoria, biblioteca grande, etc.). Pero no tienes mucho espacio para regatear sobre los detalles: toma el paquete completo o nada.
Incluso si esos idiomas pueden optimizar algún código para ejecutarse más rápido que el código compilado, el enfoque completo es (en mi humilde opinión) ineficiente. ¡Imagínese conduciendo todos los días 5 millas hasta su lugar de trabajo, con un camión! Es cómodo, se siente bien, estás a salvo (zona de deformación extrema) y después de pisar el acelerador por algún tiempo, ¡incluso será tan rápido como un auto estándar! ¿Por qué no todos tenemos un camión para conducir al trabajo? ;)
En C ++ obtienes lo que pagas, ni más ni menos.
Citando a Bjarne Stroustrup: "C ++ es mi lenguaje de recolección de basura favorito porque genera tan poca basura" .
Los lenguajes de máquina virtual es poco probable que superan a los lenguajes compilados, sino que pueden conseguir lo suficientemente cerca que no importa, por (al menos) las siguientes razones (estoy hablando para Java aquí, ya que nunca he hecho C #).
1 / El entorno de ejecución de Java es generalmente capaz de detectar piezas de código que se ejecutan con frecuencia y realizar la compilación (JIT) justo a tiempo de esas secciones para que, en el futuro, corren a la velocidad compilado completo.
2 / porciones extensas de las bibliotecas Java se compilan de manera que, cuando se llama a una función de biblioteca, que está ejecutando el código compilado, no se interpreta. Puede ver el código (en C) descargando el OpenJDK.
3 / A menos que estés haciendo cálculos masivos, la mayor parte del tiempo el programa se ejecuta, es de espera para la entrada de un ser humano muy lento (relativamente hablando).
4 / Dado que una gran parte de la validación del código de bytes de Java se realiza en el momento de la carga de la clase, la sobrecarga normal de los controles de tiempo de ejecución se reduce considerablemente.
5 / En el peor de los casos, el código de rendimiento intensivo puede ser extraído a un módulo compilado y llamó desde Java (ver JNI) para que se ejecute a toda velocidad.
En resumen, el código de bytes de Java nunca superan el lenguaje máquina nativo, pero hay maneras de mitigar esto. La gran ventaja de Java (como yo lo veo) es la enorme biblioteca estándar y la naturaleza multiplataforma.
Yo miro desde algunos puntos diferentes.
- Teniendo en cuenta el tiempo y los recursos infinitos, se lograron o código no administrado ser más rápido? Claramente, la respuesta es que el código no administrado puede siempre por lo menos un lazo de código administrado en este aspecto - que en el peor de los casos, que acababa de código el código administrado solución.
- Si se toma un programa en un idioma, y directamente traducirlo a otro, cuanto peor va a realizar? Probablemente mucho, por cualquier dos idiomas. La mayoría de los idiomas requerir diferentes optimizaciones y tienen diferentes trampas. Micro-rendimiento es a menudo mucho de conocer estos detalles.
- Given finite time and resources, which of two languages will produce a better result? This is the most interesting question, as while a managed language may produce slightly slower code (given a program reasonably written for that language), that version will likely be done sooner, allowing for more time spent on optimization.
Para cualquier cosa necesidad de mucha velocidad, la JVM sólo llama a una implementación en C ++, por lo que es una cuestión más de lo bien que sus bibliotecas son de lo bien que la JVM es para la mayoría de las cosas relacionadas con OS. La recolección de basura reduce la memoria a la mitad, pero el uso de algunas de las características STL e impulsar más elegantes tendrá el mismo efecto pero con muchas veces el potencial de errores.
Si usted está usando C ++ bibliotecas y un montón de sus características de alto nivel en un gran proyecto con muchas clases que probablemente va a acabar más lento que usar una JVM. Excepto mucho más propenso a errores.
Sin embargo, el beneficio de C ++ es que le permite optimizar usted mismo, si le pegan con lo que el compilador / JVM. Si usted hace sus propios contenedores, escriba su propia gestión de memoria que está alineado, use SIMD, y soltar para el montaje aquí y allá, se puede acelerar por lo menos veces 4x-2x más de lo que la mayoría de los compiladores de C ++ lo harán por su cuenta. Para algunas operaciones, 16x-32x. Eso está usando los mismos algoritmos, si se utiliza mejores algoritmos y paralelizar, los aumentos pueden ser dramáticos, a veces miles de veces más rápido que los métodos usados comúnmente.
Una respuesta muy corta: Dado un presupuesto fijo va a lograr un mejor rendimiento de aplicaciones Java de una aplicación C ++ (contemplaciones de ROI) Además plataforma Java ha perfiladores más decente, que le ayudará a identificar sus puntos de acceso más rápido
Ve y lee sobre HP Labs Dynamo , un intérprete para PA-8000 que se ejecuta en PA-8000, y con frecuencia lleva a cabo programas más rápido que lo hacen de forma nativa. Entonces no se parecerá en absoluto sorprendente!
No piensa en él como un "paso intermedio" - la ejecución de un programa implica un montón de otras medidas ya, en cualquier idioma.
A menudo se reduce a:
programas tienen puntos calientes, por lo que incluso si usted es más lenta en funcionamiento el 95% del cuerpo de código que tiene que ejecutar, que todavía puede ser el rendimiento competitivo si eres más rápido al 5% caliente
un HLL sabe más acerca de su intención de un LLL como C / C ++, por lo que puede generar un código más optimizado (OCaml tiene aún más, y en la práctica es a menudo más rápido)
un compilador JIT tiene una gran cantidad de información que un compilador estático no lo hace (como, los datos reales le sucede que tiene esta vez)
un compilador JIT puede hacer optimizaciones en tiempo de ejecución que enlazadores tradicionales no son realmente autorizados a hacer (como la reordenación de las ramas por lo que el caso común es plana, o inlining llamadas a las bibliotecas)
Con todo, C / C ++ son lenguajes bastante pésimo para el rendimiento: hay relativamente poca información sobre los tipos de datos, no hay información acerca de sus datos, y no hay tiempo de ejecución dinámico para permitir mucho en el camino de la optimización del tiempo de ejecución.
Es posible obtener ráfagas cortas cuando Java o CLR es más rápido que C ++, pero en general el rendimiento es peor para la vida de la aplicación: ver www.codeproject.com/KB/dotnet/RuntimePerformance.aspx para algunos resultados para eso.
Aquí está la respuesta del acantilado Click: http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain
JIT vs. compilador estático
Como ya se dijo en las publicaciones anteriores, JIT puede compilar IL / bytecode en código nativo en tiempo de ejecución. Se mencionó el costo de eso, pero no hasta su conclusión:
JIT tiene un gran problema: no puede compilar todo: la compilación JIT lleva tiempo, por lo que el JIT compilará solo algunas partes del código, mientras que un compilador estático producirá un binario nativo completo: para algún tipo de programa, el estático compilador simplemente superará fácilmente el JIT.
Por supuesto, C # (o Java o VB) suele ser más rápido para producir una solución viable y robusta que C ++ (aunque solo sea porque C ++ tiene una semántica compleja, y la biblioteca estándar de C ++, aunque interesante y poderosa, es bastante pobre en comparación con la completa alcance de la biblioteca estándar de .NET o Java), por lo general, la diferencia entre C ++ y .NET o Java JIT no será visible para la mayoría de los usuarios, y para aquellos binarios que son críticos, todavía puede llamar al procesamiento de C ++ desde C # o Java (incluso si este tipo de llamadas nativas pueden ser bastante costosas en sí mismas) ...
Metaprogramación C ++
Tenga en cuenta que, por lo general, está comparando el código de tiempo de ejecución de C ++ con su equivalente en C # o Java. Pero C ++ tiene una característica que puede superar a Java / C #, es la metaprogramación de plantillas: el procesamiento del código se realizará en tiempo de compilación (aumentando así el tiempo de compilación), dando como resultado cero (o casi cero) tiempo de ejecución.
Todavía he visto un efecto de vida real en esto (jugué solo con conceptos, pero para entonces, la diferencia eran segundos de ejecución para JIT, y cero para C ++), pero vale la pena mencionar esto, junto con la metaprogramación de la plantilla de hecho no trivial...
Editar 2011-06-10: En C ++, jugar con tipos se hace en tiempo de compilación, lo que significa producir código genérico que llama código no genérico (por ejemplo, un analizador genérico de cadena a tipo T, llama a API de biblioteca estándar para tipos T reconoce, y hacer que el analizador sea fácilmente extensible por su usuario) es muy fácil y muy eficiente, mientras que el equivalente en Java o C # es doloroso para escribir, y siempre será más lento y resuelto en el tiempo de ejecución incluso cuando los tipos se conocen en tiempo de compilación. lo que significa que tu única esperanza es que JIT integre todo.
...
Editar 2011-09-20: El equipo detrás de Blitz ++ ( Homepage , Wikipedia ) fue por ese camino, y aparentemente, su objetivo es alcanzar el rendimiento de FORTRAN en cálculos científicos moviéndose tanto como sea posible de la ejecución en tiempo de ejecución al tiempo de compilación, a través de la metaprogramación de plantillas C ++ . Así que el " Todavía veo un efecto de la vida real en esta " parte que escribí arriba aparentemente existe en la vida real.
Uso nativo de memoria C ++
C ++ tiene un uso de memoria diferente de Java / C #, y por lo tanto, tiene diferentes ventajas / defectos.
Sin importar la optimización de JIT, nada irá tan rápido como el acceso directo a la memoria (ignoremos por un momento los cachés de los procesadores, etc.). Por lo tanto, si tiene datos contiguos en la memoria, acceder a ellos a través de punteros C ++ (es decir, punteros C ... Vamos a dar a Caesar su debido tiempo) irá más rápido que en Java / C #. Y C ++ tiene RAII, lo que hace que el procesamiento sea mucho más fácil que en C # o incluso en Java. C ++ no necesita using
para determinar la existencia de sus objetos. Y C ++ no tiene una cláusula finally
. Esto no es un error.
:-)
Y a pesar de las estructuras de tipo primitivo de C #, los objetos de C ++ "en la pila" no costarán nada en la asignación y destrucción, y no necesitarán GC para trabajar en un hilo independiente para hacer la limpieza.
En cuanto a la fragmentación de memoria, los asignadores de memoria en 2008 no son los antiguos asignadores de memoria de 1980 que generalmente se comparan con un GC: la asignación de C ++ no se puede mover en la memoria, es cierto, pero como en un sistema de archivos Linux: ¿Quién necesita el disco duro? ¿desfragmentando cuando la fragmentación no ocurre? El uso del asignador correcto para la tarea correcta debe ser parte del kit de herramientas para desarrolladores de C ++. Ahora, escribir asignadores no es fácil, y entonces, la mayoría de nosotros tenemos mejores cosas que hacer, y para su mayor uso, RAII o GC es más que suficiente.
Edit 2011-10-04: ejemplos de asignadores eficientes: en Windows, desde Vista, Low Heap de fragmentación está habilitado de forma predeterminada. Para versiones anteriores, el LFH se puede activar llamando a la función WinAPI HeapSetInformation ). En otros sistemas operativos, se proporcionan asignadores alternativos (consulte https://secure.wikimedia.org/wikipedia/en/wiki/Malloc para obtener una lista)
Ahora, el modelo de memoria se está volviendo algo más complicado con el aumento de la tecnología multinúcleo y multihilo. En este campo, supongo que .NET tiene la ventaja, y Java, me dijeron, mantuvo la ventaja. Es fácil para un hacker "al descubierto" alabar su código "cerca de la máquina". Pero ahora, es bastante más difícil producir un mejor ensamblaje a mano que dejar que el compilador haga su trabajo. Para C ++, el compilador usualmente es mejor que el hacker desde hace una década. Para C # y Java, esto es aún más fácil.
Aún así, el nuevo estándar C ++ 0x impondrá un modelo de memoria simple a los compiladores C ++, que estandarizará (y simplificará) el código eficaz de multiprocesamiento / paralelo / subprocesamiento en C ++, y hará que las optimizaciones sean más fáciles y seguras para los compiladores. Pero luego, veremos en algunos años si sus promesas se cumplen.
C ++ / CLI vs. C # / VB.NET
Nota: En esta sección, estoy hablando de C ++ / CLI, es decir, el C ++ alojado por .NET, no el C ++ nativo.
La semana pasada, tuve un entrenamiento en optimización .NET, y descubrí que el compilador estático es muy importante de todos modos. Tan importante que JIT.
El mismo código compilado en C ++ / CLI (o su antecesor, Managed C ++) podría ser veces más rápido que el mismo código producido en C # (o VB.NET, cuyo compilador produce el mismo IL que C #).
Debido a que el compilador estático C ++ era mucho mejor para producir código ya optimizado que C #.
Por ejemplo, la función en línea en .NET está limitada a funciones cuyo bytecode es inferior o igual a 32 bytes de longitud. Por lo tanto, algún código en C # producirá un acceso de 40 bytes, que el JIT nunca incluirá. El mismo código en C ++ / CLI producirá un acceso de 20 bytes, que será subrayado por el JIT.
Otro ejemplo son las variables temporales, que simplemente compila el compilador de C ++ mientras aún se mencionan en la IL producida por el compilador de C #. La optimización de la compilación estática de C ++ dará como resultado menos código, por lo tanto, autoriza una optimización de JIT más agresiva, nuevamente.
Se especuló que el motivo de esto era el hecho de que el compilador C ++ / CLI se beneficiaba de las vastas técnicas de optimización del compilador nativo de C ++.
Conclusión
Me encanta C ++.
Pero hasta donde yo lo veo, C # o Java son en conjunto una mejor apuesta. No porque sean más rápidos que C ++, sino porque cuando agrega sus cualidades, terminan siendo más productivos, necesitan menos capacitación y tienen bibliotecas estándar más completas que C ++. Y como para la mayoría de los programas, sus diferencias de velocidad (de una manera u otra) serán insignificantes ...
Editar (06/06/2011)
Mi experiencia en C # / .NET
Ahora tengo 5 meses de codificación C # casi exclusiva (lo que se suma a mi CV ya lleno de C ++ y Java, y un toque de C ++ / CLI).
Jugué con WinForms (Ahem ...) y WCF (¡genial!) Y WPF (¡Genial! Tanto a través de XAML como C # sin formato. WPF es tan fácil que creo que Swing simplemente no se puede comparar), y C # 4.0.
La conclusión es que si bien es más fácil / rápido producir un código que funcione en C # / Java que en C ++, es mucho más difícil producir un código fuerte, seguro y robusto en C # (y aún más difícil en Java) que en C ++. Las razones abundan, pero se puede resumir por:
- Los genéricos no son tan potentes como las plantillas ( intente escribir un método Parse genérico eficiente (de cadena a T), o un equivalente eficiente de boost :: lexical_cast en C # para comprender el problema )
- RAII no tiene rival ( GC todavía puede tener fugas (sí, tuve que manejar ese problema) y solo manejará la memoria. Incluso el uso de C # no es tan fácil y poderoso porque es difícil escribir las implementaciones de Disposición correctas )
- C #
readonly
y Javafinal
no son tan útiles como elconst
C ++ ( No hay forma de que puedas exponer datos complejos de solo lectura (un Árbol de nodos, por ejemplo) en C # sin trabajo tremendo, mientras que es una característica incorporada de C ++. Los datos son inmutables una solución interesante, pero no todo puede hacerse inmutable, por lo que ni siquiera es suficiente, de lejos ).
Por lo tanto, C # sigue siendo un lenguaje agradable siempre que desee algo que funcione, pero un lenguaje frustrante en el momento que desee algo que siempre y de manera segura funcione.
Java es aún más frustrante, ya que tiene los mismos problemas que C #, y más: al carecer del equivalente de C # using
palabra clave, un colega muy hábil pasó demasiado tiempo asegurándose de que sus recursos estuvieran correctamente liberados, mientras que el equivalente en C ++ han sido fáciles (usando destructores y punteros inteligentes).
Así que supongo que la ganancia de productividad de C # / Java es visible para la mayoría de los códigos ... hasta el día en que necesite que el código sea lo más perfecto posible. Ese día, sabrás dolor. (No creerá lo que se le pide a nuestro servidor y las aplicaciones GUI ...).
Acerca del lado del servidor Java y C ++
Mantuve contacto con los equipos de servidores (trabajé 2 años entre ellos, antes de volver al equipo de GUI), en el otro lado del edificio, y aprendí algo interesante.
En los últimos años, la tendencia fue hacer que las aplicaciones de servidor Java estuvieran destinadas a reemplazar las antiguas aplicaciones de servidor C ++, ya que Java tiene muchos marcos / herramientas, y es fácil de mantener, implementar, etc., etc.
... Hasta que el problema de la baja latencia levantó su fea cabeza en los últimos meses. Entonces, las aplicaciones de servidor de Java, sin importar la optimización que intentara nuestro equipo experto de Java, simplemente y limpiamente perdieron la carrera contra el viejo servidor de C ++, no realmente optimizado.
Actualmente, la decisión es mantener los servidores Java para uso común donde el rendimiento es importante, no se preocupa por el objetivo de baja latencia y optimizar de forma agresiva las aplicaciones de servidor C ++ que ya son más rápidas para necesidades de baja latencia y latencia ultrabaja.
Conclusión
Nada es tan simple como se esperaba.
Java, y aún más C #, son idiomas geniales, con amplias bibliotecas y marcos estándar, donde puede codificar rápidamente y obtener resultados muy pronto.
Pero cuando se necesita potencia bruta, optimizaciones potentes y sistemáticas, una sólida compatibilidad con el compilador, potentes funciones de lenguaje y absoluta seguridad, Java y C # hacen que sea difícil ganar los últimos porcentajes de calidad que falta pero que necesitan para mantenerse por encima de la competencia.
Es como si necesitaras menos tiempo y desarrolladores menos experimentados en C # / Java que en C ++ para producir un código de calidad promedio, pero por otro lado, en el momento en que necesitas un código de calidad excelente a perfecto, de repente fue más fácil y rápido obtener los resultados justo en C ++.
Por supuesto, esta es mi propia percepción, tal vez limitada a nuestras necesidades específicas.
Pero aún así, es lo que sucede hoy, tanto en los equipos de GUI como en los equipos del lado del servidor.
Por supuesto, actualizaré esta publicación si ocurre algo nuevo.
Editar (2011-06-22)
"Encontramos que en cuanto a rendimiento, C ++ gana por un amplio margen. Sin embargo, también requirió los esfuerzos de ajuste más extensos, muchos de los cuales se realizaron con un nivel de sofisticación que no estaría disponible para el programador promedio.
[...] La versión de Java fue probablemente la más simple de implementar, pero la más difícil de analizar para el rendimiento. Específicamente, los efectos en torno a la recolección de basura fueron complicados y muy difíciles de sintonizar ".
Fuentes:
- https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf
- http://www.computing.co.uk/ctg/news/2076322/-winner-google-language-tests
Editar (2011-09-20)
"La palabra en Facebook es que el '' código C ++ razonablemente escrito simplemente se ejecuta rápido '' , lo que subraya el enorme esfuerzo dedicado a optimizar el código PHP y Java. Paradójicamente, el código C ++ es más difícil de escribir que en otros idiomas, pero el código eficiente es mucho más fácil [para escribir en C ++ que en otros idiomas] " .
- Herb Sutter en // build / , citando a Andrei Alexandrescu
Fuentes:
Cada vez que hablo de desempeño administrado frente a no gestionado, me gusta señalar que la serie Rico (y Raymond) sí compararon las versiones C ++ y C # de un diccionario chino / inglés. Esta búsqueda en Google te permitirá leer por ti mismo, pero me gusta el resumen de Rico.
Entonces, ¿estoy avergonzado por mi aplastante derrota? Apenas. El código administrado obtuvo un muy buen resultado para casi ningún esfuerzo. Para vencer al Raymond administrado, tenía que:
- Escribe sus propias cosas de E / S de archivos
- Escribe su propia clase de cuerda
- Escribe su propio asignador
- Escribe su propio mapeo internacional
Por supuesto, utilizó bibliotecas disponibles de nivel inferior para hacer esto, pero eso aún requiere mucho trabajo. ¿Puedes llamar a lo que queda de un programa STL? No lo creo, creo que mantuvo la clase std :: vector, que en última instancia nunca fue un problema y mantuvo la función de búsqueda. Casi todo lo demás se ha ido.
Entonces, sí, definitivamente puedes vencer al CLR. Raymond puede hacer que su programa sea aún más rápido, creo.
Curiosamente, el tiempo para analizar el archivo según lo informado por los temporizadores internos de ambos programas es aproximadamente el mismo: 30 ms para cada uno. La diferencia está en la sobrecarga.
Para mí, la conclusión es que se necesitaron 6 revisiones para que la versión no administrada superara a la versión administrada que era un puerto simple del código original no administrado. Si necesita hasta el último bit de rendimiento (y tiene el tiempo y la experiencia para hacerlo), tendrá que ir sin control, pero para mí, tomaré la ventaja de orden de magnitud que tengo en las primeras versiones sobre el 33 % Ganaré si lo intento 6 veces.
Mi entendimiento es que C / C ++ produce código nativo para funcionar en una arquitectura de máquina en particular. Por el contrario, lenguajes como Java y C # ejecutar en la parte superior de una máquina virtual que abstrae la arquitectura nativa. Lógicamente parecería imposible para Java o C # para que coincida con la velocidad de C ++ debido a este paso intermedio, sin embargo me han dicho que los últimos compiladores ( "hot spot") pueden alcanzar esta velocidad o incluso excederlo.
Eso es ilógico. El uso de una representación intermedia no se degrada inherentemente rendimiento. Por ejemplo, llvm-gcc compila C y C ++ a través de LLVM IR (que es una máquina infinita-registro virtual) a código nativo y logra un excelente rendimiento (a menudo superando GCC).
Tal vez esto es más una cuestión de compilador que una cuestión de la lengua, pero ¿alguien puede explicar de manera clara Inglés cómo es posible que uno de estos lenguajes de máquina virtual para obtener mejores resultados que una lengua nativa?
Aquí hay unos ejemplos:
Las máquinas virtuales con la compilación JIT facilitan la generación de código en tiempo de ejecución (por ejemplo,
System.Reflection.Emit
en .NET) para que pueda compilar el código generado en la marcha en lenguajes como C # y F #, sino que debe recurrir a la escritura de un intérprete comparativamente lento en C o C ++. Por ejemplo, para poner en práctica las expresiones regulares.Las partes de la máquina virtual (por ejemplo, la barrera de escritura y asignador) se escriben a menudo en ensamblador codificado a mano debido a que C y C ++ no generan código lo suficientemente rápido. Si un programa hace hincapié en estas partes de un sistema, entonces podría concebiblemente superar cualquier cosa que pueda ser escrito en C o C ++.
La vinculación dinámica de código nativo requiere la conformidad con un ABI que pueden impedir el rendimiento y obvia la optimización de todo el programa, mientras que une normalmente se difiere de las máquinas virtuales y pueden beneficiarse de las optimizaciones de todo el programa (como genéricos reificadas de .NET).
También me gustaría hacer frente a algunos problemas con la respuesta altamente upvoted de paercebal anterior (porque alguien mantiene la supresión de mis comentarios en su respuesta) que presenta una visión contra-productiva polarizada:
El procesamiento de código se realiza en tiempo de compilación ...
De ahí que la plantilla metaprogramming sólo funciona si el programa está disponible en tiempo de compilación que a menudo no es el caso, por ejemplo, es imposible escribir una biblioteca de expresiones regulares competitivamente performant la vainilla C ++, ya que es incapaz de generación de código de tiempo de ejecución (un aspecto importante de metaprogramming).
... jugar con tipos se realiza en tiempo de compilación ... el equivalente en Java o C # es dolorosa, en el mejor de escribir, y siempre será más lento y resuelta en tiempo de ejecución, incluso cuando se conocen los tipos en tiempo de compilación.
En C #, que sólo es cierto de los tipos de referencia y no es cierto para los tipos de valor.
No importa la optimización JIT, nada va a ir más rápido que tiene acceso directo a la memoria del puntero ... si tiene datos contiguos en la memoria, para acceder a él a través de punteros de C ++ (es decir, C punteros ... vamos a darle su debida César) se va veces más rápido que en Java / C #.
La gente se ha observado Java superando a C ++ en la prueba del índice de referencia SOR SciMark2 precisamente porque punteros impiden optimizaciones relacionadas aliasing.
También digno de mención que hace .NET escribir especialización de los genéricos a través de las librerías enlazadas dinámicamente después de enlazar mientras que C ++ no puede porque las plantillas deben ser resueltos antes de enlazar. Y, obviamente, las grandes genéricos ventaja que tienen sobre las plantillas de mensajes de error es comprensible.
En general, C # y Java pueden ser igual o más rápidos porque el compilador JIT, un compilador que compila su IL la primera vez que se ejecuta, puede hacer optimizaciones que un programa compilado en C ++ no puede porque puede consultar la máquina. Puede determinar si la máquina es Intel o AMD; Pentium 4, Core Solo o Core Duo; o si es compatible con SSE4, etc.
Un programa C ++ debe compilarse de antemano, generalmente con optimizaciones mixtas para que funcione decentemente bien en todas las máquinas, pero no está optimizado tanto como podría para una sola configuración (es decir, procesador, conjunto de instrucciones, otro hardware).
Además, ciertas características del lenguaje permiten al compilador en C # y Java hacer suposiciones sobre su código que le permite optimizar ciertas partes que no son seguras para el compilador de C / C ++. Cuando tiene acceso a punteros, hay muchas optimizaciones que simplemente no son seguras.
Además, Java y C # pueden hacer asignaciones de pila de manera más eficiente que C ++ porque la capa de abstracción entre el recolector de basura y su código le permite hacer toda su compresión de pila a la vez (una operación bastante costosa).
Ahora no puedo hablar sobre Java en este punto, pero sé que C #, por ejemplo, eliminará métodos y llamadas a métodos cuando sepa que el cuerpo del método está vacío. Y usará este tipo de lógica en todo su código.
Como puede ver, hay muchas razones por las cuales ciertas implementaciones C # o Java serán más rápidas.
Ahora todo esto, optimizaciones específicas se pueden hacer en C ++ que eliminarán todo lo que se puede hacer con C #, especialmente en el ámbito de los gráficos y en cualquier momento que esté cerca del hardware. Los indicadores hacen maravillas aquí.
Entonces, dependiendo de lo que estés escribiendo, iría con uno u otro. Pero si estás escribiendo algo que no depende del hardware (controlador, videojuego, etc.), no me preocuparía el rendimiento de C # (una vez más no puedo hablar sobre Java). Lo hará bien.
Uno del lado de Java, @Swati señala un buen artículo:
Me gusta la respuesta de Orion Adrian , pero hay otro aspecto.
La misma pregunta se planteó hace décadas sobre el lenguaje ensamblador frente a los lenguajes "humanos" como FORTRAN. Y parte de la respuesta es similar.
Sí, un programa C ++ es capaz de ser más rápido que C # en cualquier algoritmo dado (¿no trivial?), Pero el programa en C # a menudo será tan rápido o más rápido que una implementación "ingenua" en C ++, y una versión optimizada en C ++ tardará más tiempo en desarrollarse, y aún podría superar la versión C # por un margen muy pequeño. Entonces, ¿realmente vale la pena?
Tendrá que responder a esa pregunta uno a uno.
Dicho esto, soy un fanático de C ++ desde hace mucho tiempo, y creo que es un lenguaje increíblemente expresivo y poderoso, a veces subestimado. Pero en muchos problemas de la "vida real" (para mí personalmente, eso significa "del tipo que me pagan para resolver"), C # hará el trabajo más pronto y más seguro.
¿La mayor multa que pagas? Muchos programas .NET y Java son cerdos de memoria. He visto que las aplicaciones .NET y Java toman "cientos" de megabytes de memoria, cuando los programas C ++ de complejidad similar apenas rayan las "decenas" de MB.
Orion Adrian , deja que invertir la post para ver cómo infundada sus observaciones son, pues una gran cantidad se puede decir de C ++ también. Y diciéndole que Java / C # compilador optimizar distancia función vacía realmente hacer que suene como si no mi experto en optimización, porque a) ¿por qué un programa real contener funciones vacías, a excepción de muy mal código heredado, b) que no es realmente optimización borde negro y sangrado.
Aparte de esa frase, que despotricó abiertamente sobre los punteros, pero no los objetos en Java y C #, básicamente, trabaja como punteros en C ++? Que no se superponen? Que no puede ser nulo? C (y la mayoría de las implementaciones de C ++) tiene la palabra clave restringir, ambos tienen tipos de valor, C ++ tiene referencia de generación de valor con garantía de no nulo. Qué hacer Java y C # oferta?
>>>>>>>>>>
Generalmente, C y C ++ pueden ser tan rápido o más rápido porque el compilador AOT - un compilador que compila el código antes de la implementación, de una vez por todas, en su gran memoria del servidor que muchos de muñones - puede hacer optimizaciones que un programa en C # compilado no puede porque tiene un montón de tiempo para hacerlo. El compilador puede determinar si la máquina es Intel o AMD; Pentium 4, Core Solo o Core Duo; o si es compatible con SSE4, etc, y si su compilador no admite el envío de tiempo de ejecución, puede resolver por sí mismo que mediante la implementación de un puñado de binarios especializados.
Un programa en C # es compilado comúnmente a ejecutarlo para que se ejecute decentemente bien en todas las máquinas, pero no está optimizado tanto como lo podría ser para una sola configuración (es decir, procesador, conjunto de instrucciones, otro hardware), y que tiene que pasar algún tiempo primero. Características tales como la fisión del bucle, la inversión de bucle, vectorización automática, optimización del programa conjunto, la expansión plantilla, IPO, y muchos más, son muy difíciles de ser resuelto por completo todos y de una manera que no molesta al usuario final.
Además ciertas características del lenguaje permiten que el compilador de C ++ o C para hacer suposiciones acerca de su código que le permite optimizar ciertas partes de distancia que simplemente no son seguros para el Java / C # compilador para hacerlo. Cuando usted no tiene acceso al ID de tipo completo de los genéricos o de un flujo de programa garantizada hay un montón de optimizaciones que no son seguros.
También C ++ y C hacen muchas asignaciones de pila a la vez con un solo registro de incremento, lo que sin duda es más eficiente que Javas y C # como asignaciones para la capa de abstracción entre el recolector de basura y su código.
Ahora no puedo hablar en nombre de Java en este punto siguiente, pero sé que los compiladores de C ++, por ejemplo, en realidad se retire métodos y las llamadas de método cuando se sabe que el cuerpo del método está vacío, se encargará de eliminar subexpresiones comunes, se puede tratar de volver a intentar para encontrar un uso óptimo registro, no hace cumplir la comprobación de límites, se autovectorize bucles y bucles internos y solera interior al exterior, se mueve condicionales de bucles, se divide y bucles unsplits. Se ampliará std :: vector en matrices nativas cero generales como desee hacer el camino C. Lo hará optimmizations de procedimiento inter. Se construirá valores de retorno directamente en el lugar de la persona que llama. Que se pliega y propagar expresiones. Se reordenará datos en una forma agradable y caché. Lo hará roscado salto. Se le permite escribir compilar trazadores de rayos en tiempo de ejecución con una sobrecarga cero.Esto hará que las optimizaciones basadas muy caro gráfico. Lo hará reducción de la resistencia, que sustituye fueron determinados códigos con código sintácticamente totalmente desigual, pero semánticamente equivalentes (la antigua "foo XOR, foo" es sólo el más simple, aunque la optimización antigua de este tipo). Si lo pide amablemente, es posible omitir los estándares IEEE punto flotante y permitir aún más optimizaciones como punto flotante operando reordenamiento. Después de que se ha dado masajes y masacrados su código, podría repetir todo el proceso, porque a menudo, ciertas optimizaciones sientan las bases para optimizaciones incluso certainer. También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.eran reemplaza ciertos códigos con código sintácticamente totalmente desigual, pero semánticamente equivalentes (la antigua "foo XOR, foo" es sólo el más simple, aunque la optimización antigua de este tipo). Si lo pide amablemente, es posible omitir los estándares IEEE punto flotante y permitir aún más optimizaciones como punto flotante operando reordenamiento. Después de que se ha dado masajes y masacrados su código, podría repetir todo el proceso, porque a menudo, ciertas optimizaciones sientan las bases para optimizaciones incluso certainer. También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.eran reemplaza ciertos códigos con código sintácticamente totalmente desigual, pero semánticamente equivalentes (la antigua "foo XOR, foo" es sólo el más simple, aunque la optimización antigua de este tipo). Si lo pide amablemente, es posible omitir los estándares IEEE punto flotante y permitir aún más optimizaciones como punto flotante operando reordenamiento. Después de que se ha dado masajes y masacrados su código, podría repetir todo el proceso, porque a menudo, ciertas optimizaciones sientan las bases para optimizaciones incluso certainer. También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.Si lo pide amablemente, es posible omitir los estándares IEEE punto flotante y permitir aún más optimizaciones como punto flotante operando reordenamiento. Después de que se ha dado masajes y masacrados su código, podría repetir todo el proceso, porque a menudo, ciertas optimizaciones sientan las bases para optimizaciones incluso certainer. También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.Si lo pide amablemente, es posible omitir los estándares IEEE punto flotante y permitir aún más optimizaciones como punto flotante operando reordenamiento. Después de que se ha dado masajes y masacrados su código, podría repetir todo el proceso, porque a menudo, ciertas optimizaciones sientan las bases para optimizaciones incluso certainer. También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.También podría simplemente volver a intentar con los parámetros barajan y ver cómo las otras puntuaciones variantes en su clasificación interna. Y va a utilizar este tipo de lógica a través de su código.
Así como se puede ver, hay un montón de razones por las que ciertas implementaciones de C ++ o C será más rápido.
Ahora bien, esta todo dicho, muchas optimizaciones se pueden hacer en C ++ que se lleve el aire cualquier cosa que usted podría hacer con C #, especialmente en el procesamiento de números, en tiempo real y el reino de proximidad al metal, pero no exclusivamente allí. Ni siquiera tiene que tocar un solo puntero a recorrido un largo camino.
Así que dependiendo de lo que estás escribiendo Me gustaría ir con uno u otro. Pero si usted está escribiendo algo que no depende del hardware (conductor, juego de vídeo, etc), yo no me preocuparía por el rendimiento de C # (de nuevo, no puede hablar acerca de Java). Se va a hacer muy bien.
<<<<<<<<<<
En general, algunos de los argumentos generalizados puede sonar fresco en puestos específicos, pero por lo general no suena ciertamente creíble.
De todas formas, para hacer la paz: AOT es grande, como es JIT . La única respuesta correcta puede ser: Depende. Y las personas que verdaderamente inteligentes saben que se puede utilizar lo mejor de ambos mundos de todos modos.