una - ¿Cuánto más rápido es C++ que C#?
que lenguaje de programacion aprender (27)
Aplicaciones que requieren acceso intensivo a la memoria, por ejemplo. la manipulación de la imagen suele estar mejor escrita en un entorno no administrado (C ++) que administrada (C #). Los bucles internos optimizados con aritmética de punteros son mucho más fáciles de controlar en C ++. En C # es posible que deba recurrir a un código inseguro para incluso acercarse al mismo rendimiento.
¿O es ahora al revés?
Por lo que he escuchado, hay algunas áreas en las que C # demuestra ser más rápido que C ++, pero nunca he tenido las agallas para probarlo por mí mismo.
Pensé que cualquiera de ustedes podría explicar estas diferencias en detalle o señalarme el lugar correcto para obtener información sobre esto.
Bueno, eso depende. Si el código de bytes se traduce en código de máquina (y no solo en JIT) (quiero decir, si ejecuta el programa) y si su programa usa muchas asignaciones / desasignaciones, podría ser más rápido porque el algoritmo GC solo necesita una pasada (teóricamente) a través de toda la memoria una vez, pero las llamadas normales malloc / realloc / free C / C ++ causan una sobrecarga en cada llamada (sobrecarga de llamadas, sobrecarga de la estructura de datos, falta de memoria caché;)).
Por lo tanto, es teóricamente posible (también para otros idiomas de GC).
Realmente no veo la desventaja extrema de no poder usar la metaprogramming con C # para la mayoría de las aplicaciones, porque la mayoría de los programadores no lo usan de todos modos.
Otra gran ventaja es que el SQL, como la "extensión" de LINQ , brinda oportunidades para que el compilador optimice las llamadas a las bases de datos (en otras palabras, el compilador podría compilar todo el LINQ en un binario "blob" donde las funciones llamadas están en línea o para su uso optimizado, pero estoy especulando aquí).
C # puede no ser más rápido, pero hace que YOU / ME sea más rápido. Esa es la medida más importante para lo que hago. :)
C ++ (o C para el caso) le brinda un control detallado sobre sus estructuras de datos. Si quieres un poco de twiddle tienes esa opción. Las aplicaciones grandes administradas de Java o .NET (OWB, Visual Studio 2005 ) que utilizan las estructuras de datos internas de las bibliotecas de Java / .NET llevan el equipaje consigo. He visto sesiones de diseño de OWB utilizando más de 400 MB de RAM y BIDS para diseño de cubo o ETL que también llegan a los 100 MB.
En una carga de trabajo predecible (como la mayoría de los puntos de referencia que repiten un proceso muchas veces), un JIT puede proporcionarle un código que está lo suficientemente optimizado para que no haya una diferencia práctica.
OMI en aplicaciones grandes, la diferencia no es tanto el JIT como las estructuras de datos que utiliza el código. Cuando una aplicación tenga mucha memoria, obtendrá un uso de caché menos eficiente. Las fallas de caché en las CPU modernas son bastante caras. Donde C o C ++ realmente gana es donde puede optimizar el uso de las estructuras de datos para jugar bien con el caché de la CPU.
C / C ++ puede funcionar mucho mejor en programas donde hay arreglos grandes o bucles / iteración pesados sobre arreglos (de cualquier tamaño). Esta es la razón por la que los gráficos son generalmente mucho más rápidos en C / C ++, porque las operaciones de matriz pesada subyacen en casi todas las operaciones gráficas. .NET es notoriamente lento en las operaciones de indexación de matrices debido a todas las comprobaciones de seguridad, y esto es especialmente cierto para matrices multidimensionales (y, sí, las matrices de C # rectangulares son incluso más lentas que las matrices de C # irregulares).
Las bonificaciones de C / C ++ son más pronunciadas si se adhiere directamente a los punteros y evita los contenedores Boost, std::vector
y otros contenedores de alto nivel, así como en inline
todas las funciones pequeñas posibles. Use arreglos de la vieja escuela siempre que sea posible. Sí, necesitará más líneas de código para lograr lo mismo que hizo en Java o C # al evitar contenedores de alto nivel. Si necesita una matriz de tamaño dinámico, solo tendrá que recordar emparejar su new T[]
con una declaración de delete[]
correspondiente (o use std::unique_ptr
): el precio de la velocidad adicional es que debe codificar más cuidadosamente . Pero a cambio, puede deshacerse de la sobrecarga de la memoria administrada / recolector de basura, que puede ser fácilmente el 20% o más del tiempo de ejecución de los programas altamente orientados a objetos en Java y .NET, así como los masivos gestionados. Costos de indexación de matriz de memoria. Las aplicaciones C ++ también pueden beneficiarse de algunos modificadores de compilación ingeniosos en ciertos casos específicos.
Soy un programador experto en C, C ++, Java y C #. Recientemente tuve la rara ocasión de implementar exactamente el mismo programa algorítmico en los últimos 3 idiomas. El programa tenía muchas operaciones matriciales y matrices multidimensionales. Lo optimicé fuertemente en los 3 idiomas. Los resultados fueron típicos de lo que normalmente veo en comparaciones menos rigurosas: Java fue aproximadamente 1.3x más rápido que C # (la mayoría de las JVM están más optimizadas que el CLR), y la versión del puntero en bruto de C ++ llegó aproximadamente 2.1x más rápido que C #. Tenga en cuenta que el programa C # solo usaba código de seguridad; es mi opinión de que también podría codificarlo en C ++ antes de usar la palabra clave unsafe
.
Para que nadie piense que tengo algo en contra de C #, terminaré diciendo que C # es probablemente mi idioma favorito. Es el lenguaje de desarrollo más lógico, intuitivo y rápido que he encontrado hasta ahora. Yo hago todos mis prototipos en C #. El lenguaje C # tiene muchas ventajas pequeñas y sutiles sobre Java (sí, sé que Microsoft tuvo la oportunidad de solucionar muchas de las deficiencias de Java entrando tarde al juego y posiblemente copiando Java). ¿Brindas por la clase de Calendar
de Java a alguien? Si Microsoft alguna vez realiza un esfuerzo real para optimizar el CLR y el .NET JITter, C # podría asumir seriamente el control. Honestamente, estoy sorprendido de que no lo hayan hecho ya que hicieron muchas cosas bien en el lenguaje C #, ¿por qué no seguir con optimizaciones de compiladores? Tal vez si todos rogamos.
Comenzaré por no estar de acuerdo con una parte de la respuesta aceptada (y votada de forma correcta) a esta pregunta al afirmar:
En realidad, hay muchas razones por las que el código JIT se ejecutará más lentamente que un programa C ++ (u otro idioma sin sobrecarga del tiempo de ejecución) optimizado correctamente, incluyendo:
Los ciclos de cómputo gastados en el código JITting en tiempo de ejecución no están, por definición, disponibles para su uso en la ejecución del programa.
Cualquier ruta activa en el JITter competirá con su código para obtener información y caché de datos en la CPU. Sabemos que el caché domina el rendimiento y los lenguajes nativos como C ++, por definición, no tienen este tipo de contención.
un presupuesto de tiempo del optimizador de tiempo de ejecución es necesariamente mucho más limitado que el de un optimizador de tiempo de compilación (como señaló otro comentarista)
Conclusión: en última instancia, casi con toda seguridad podrá crear una implementación más rápida en C ++ de lo que podría en C # .
Ahora, dicho esto, cuánto más rápido realmente no es cuantificable, ya que hay demasiadas variables: la tarea, el dominio del problema, el hardware, la calidad de las implementaciones y muchos otros factores. Habrá ejecutado pruebas en su escenario para decidir si el esfuerzo y la complejidad adicionales lo vale.
Este es un tema muy largo y complejo, pero creo que vale la pena mencionar que el optimizador de tiempo de ejecución de C # es excelente, y puede realizar ciertas optimizaciones dinámicas en tiempo de ejecución que simplemente no están disponibles para C ++ con su tiempo de compilación ( optimizador estático). Incluso con esto, la ventaja suele estar profundamente en la cancha de la aplicación nativa, pero el optimizador dinámico es la razón del calificador " casi seguro", dado anteriormente.
-
En términos de rendimiento relativo, también me molestaron las cifras y las discusiones que vi en algunas otras respuestas, así que pensé que podría intervenir y, al mismo tiempo, brindar apoyo a las declaraciones que he hecho anteriormente.
Una gran parte del problema con estos puntos de referencia es que no puede escribir código C ++ como si estuviera escribiendo C # y esperar obtener resultados representativos (por ejemplo, realizar miles de asignaciones de memoria en C ++ le dará números terribles).
En cambio, escribí un código C ++ un poco más idiomático y lo comparé con el código C # que proporcionó @Wiory. Los dos cambios principales que hice en el código C ++ fueron:
1) vector usado :: reserve ()
2) aplanó la matriz 2d a 1d para lograr una mejor ubicación de caché (bloque contiguo)
C # (.NET 4.6.1)
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
Tiempo de ejecución (Lanzamiento): Inicial: 124ms, Relleno: 165ms
C ++ 14 (Clang v3.8 / C2)
#include <iostream>
#include <vector>
auto TestSuite::ColMajorArray()
{
constexpr size_t ROWS = 5000;
constexpr size_t COLS = 9000;
auto initStart = std::chrono::steady_clock::now();
auto arr = std::vector<double>();
arr.reserve(ROWS * COLS);
auto initFinish = std::chrono::steady_clock::now();
auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);
auto fillStart = std::chrono::steady_clock::now();
for(auto i = 0, r = 0; r < ROWS; ++r)
{
for (auto c = 0; c < COLS; ++c)
{
arr[i++] = static_cast<double>(r * c);
}
}
auto fillFinish = std::chrono::steady_clock::now();
auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);
return std::make_pair(initTime, fillTime);
}
Tiempo de ejecución (Lanzamiento): Inicial: 398µs (sí, eso es microsegundos), Relleno: 152 ms
Tiempos de ejecución totales: C #: 289ms, C ++ 152ms (aproximadamente un 90% más rápido)
Observaciones
Cambiar la implementación de C # a la misma implementación de matriz 1d produjo Init: 40ms, Fill: 171ms, Total: 211ms ( C ++ era casi un 40% más rápido ).
Es mucho más difícil diseñar y escribir código "rápido" en C ++ que escribir código "regular" en cualquiera de los dos idiomas.
Es (quizás) sorprendentemente fácil obtener un bajo rendimiento en C ++; Lo vimos con un rendimiento de vectores sin reservas. Y hay muchas trampas como esta.
El rendimiento de C # es bastante sorprendente si se considera todo lo que sucede en el tiempo de ejecución. Y ese rendimiento es comparativamente fácil de acceder.
Más datos anecdóticos que comparan el rendimiento de C ++ y C #: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
La conclusión es que C ++ le da mucho más control sobre el rendimiento. ¿Quieres usar un puntero? ¿Una referencia? Memoria de pila? ¿Montón? ¿Polimorfismo dinámico o eliminar la sobrecarga en tiempo de ejecución de una vtable con polimorfismo estático (a través de plantillas / CRTP)? En C ++, tiene que ... er, hacer todas estas elecciones (y más) usted mismo, idealmente para que su solución resuelva mejor el problema que está abordando.
Pregúntese si realmente quiere o necesita ese control, porque incluso para el ejemplo trivial anterior, puede ver que aunque hay una mejora significativa en el rendimiento, se requiere una inversión más profunda para acceder.
Como de costumbre, depende de la aplicación. Hay casos en los que C # es probablemente más lento, y otros casos donde C ++ es 5 o 10 veces más rápido, especialmente en casos donde las operaciones pueden ser fácilmente SIMD.
En mi experiencia (y he trabajado mucho con ambos idiomas), el principal problema con C # en comparación con C ++ es el alto consumo de memoria, y no he encontrado una buena manera de controlarlo. Fue el consumo de memoria lo que eventualmente ralentizaría el software .NET.
Otro factor es que el compilador JIT no puede permitirse demasiado tiempo para realizar optimizaciones avanzadas, ya que se ejecuta en tiempo de ejecución, y el usuario final lo notaría si tomara demasiado tiempo. Por otro lado, un compilador de C ++ tiene todo el tiempo que necesita para hacer optimizaciones en el momento de la compilación. Este factor es mucho menos significativo que el consumo de memoria, IMHO.
En teoría, para una aplicación de tipo servidor de larga ejecución, un lenguaje compilado por JIT puede llegar a ser mucho más rápido que un homólogo compilado de forma nativa. Como el lenguaje compilado JIT generalmente se compila primero a un lenguaje intermedio de nivel bastante bajo, puede hacer muchas de las optimizaciones de alto nivel en el momento de la compilación de todos modos. La gran ventaja viene en que el JIT puede continuar compilando secciones de código sobre la marcha a medida que obtiene cada vez más datos sobre cómo se utiliza la aplicación. Puede organizar las rutas de código más comunes para permitir que la predicción de bifurcación tenga éxito con la mayor frecuencia posible. Puede reorganizar bloques de código separados que a menudo se reúnen para mantenerlos en el caché. Puede gastar más esfuerzo optimizando bucles internos.
Dudo que esto sea hecho por .NET o cualquiera de los JRE, pero se estaba investigando cuando estaba en la universidad, por lo que no es irrazonable pensar que este tipo de cosas pueden encontrar su camino en el mundo real en algún momento pronto .
Es cinco naranjas más rápido. O más bien: no puede haber una respuesta general (correcta). C ++ es un lenguaje compilado estáticamente (pero también está la optimización guiada por perfil), C # se ejecuta con la ayuda de un compilador JIT. Hay tantas diferencias que preguntas como "cuánto más rápido" no se pueden responder, ni siquiera dando órdenes de magnitud.
Es una pregunta extremadamente vaga sin respuestas reales definitivas.
Por ejemplo; Prefiero jugar juegos en 3D que se crean en C ++ que en C #, porque el rendimiento es ciertamente mucho mejor. (Y sé XNA, etc., pero no se acerca en nada a la realidad).
Por otro lado, como se mencionó anteriormente; debe desarrollarse en un lenguaje que le permita hacer lo que quiera rápidamente y luego, si es necesario, optimizar.
He probado vector
en C ++ y C # equivalentes - List
y arrays 2d simples.
Estoy usando las ediciones Visual C # / C ++ 2010 Express. Ambos proyectos son aplicaciones de consola simples, las he probado en modo de depuración y liberación estándar (sin configuraciones personalizadas). Las listas de C # se ejecutan más rápido en mi PC, la inicialización de la matriz también es más rápida en C #, las operaciones matemáticas son más lentas.
Estoy usando Intel Core2Duo [email protected], C # - .NET 4.0.
Sé que la implementación de vectores es diferente de la lista de C #, pero solo quería probar las colecciones que usaría para almacenar mis objetos (y poder usar el acceso al índice).
Por supuesto, necesita borrar la memoria (digamos para cada uso de new
), pero quería mantener el código simple.
Prueba de vector de C ++ :
static void TestVector()
{
clock_t start,finish;
start=clock();
vector<vector<double>> myList=vector<vector<double>>();
int i=0;
for( i=0; i<500; i++)
{
myList.push_back(vector<double>());
for(int j=0;j<50000;j++)
myList[i].push_back(j+i);
}
finish=clock();
cout<<(finish-start)<<endl;
cout<<(double(finish - start)/CLOCKS_PER_SEC);
}
Prueba de lista C #:
private static void TestVector()
{
DateTime t1 = System.DateTime.Now;
List<List<double>> myList = new List<List<double>>();
int i = 0;
for (i = 0; i < 500; i++)
{
myList.Add(new List<double>());
for (int j = 0; j < 50000; j++)
myList[i].Add(j *i);
}
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
C ++ - array:
static void TestArray()
{
cout << "Normal array test:" << endl;
const int rows = 5000;
const int columns = 9000;
clock_t start, finish;
start = clock();
double** arr = new double*[rows];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
finish = clock();
cout << (finish - start) << endl;
start = clock();
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
finish = clock();
cout << (finish - start) << endl;
}
C # - matriz:
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
Tiempo: (Release / Debug)
C ++
- 600/606 ms array inicial,
- 200/270 ms relleno de matriz,
- 1seg / 13sec vector init & fill.
(Sí, 13 segundos, siempre tengo problemas con listas / vectores en modo de depuración).
DO#:
- 20/20 ms inici de matriz,
- 403/440 ms relleno de matriz,
- 710/742 ms lista de inicio y relleno.
Hemos tenido que determinar si C # era comparable a C ++ en rendimiento y escribí algunos programas de prueba para eso (utilizando Visual Studio 2005 para ambos idiomas). Resultó que sin recolección de basura y solo considerando el lenguaje (no el marco) C # tiene básicamente el mismo rendimiento que C ++. La asignación de memoria es mucho más rápida en C # que en C ++ y C # tiene una ligera ventaja en el determinismo cuando los tamaños de los datos aumentan más allá de los límites de la línea de caché. Sin embargo, todo esto tuvo que pagarse finalmente y existe un costo enorme en forma de resultados de rendimiento no deterministas para C # debido a la recolección de basura.
La recolección de basura es la razón principal por la que Java # NO SE PUEDE utilizar para sistemas en tiempo real.
¿Cuándo sucederá el GC?
¿Cuánto tiempo tardará?
Esto no es determinista.
Los lenguajes .NET pueden ser tan rápidos como el código C ++, o incluso más rápidos, pero el código C ++ tendrá un rendimiento más constante, ya que el tiempo de ejecución de .NET debe pausar para GC , incluso si es muy inteligente en cuanto a sus pausas.
Por lo tanto, si tiene algún código que debe ejecutarse de manera consistente y rápida sin ninguna pausa, .NET introducirá la latencia en algún momento , incluso si tiene mucho cuidado con el GC en tiempo de ejecución.
No hay una razón estricta por la que un lenguaje basado en código de bytes como C # o Java que tenga un JIT no pueda ser tan rápido como el código C ++. Sin embargo, el código C ++ solía ser significativamente más rápido durante mucho tiempo, y también hoy en día sigue siendo así en muchos casos. Esto se debe principalmente a que las optimizaciones de JIT más avanzadas son complicadas de implementar, y las realmente geniales están llegando justo ahora.
Entonces C ++ es más rápido, en muchos casos. Pero esto es solo una parte de la respuesta. Los casos en los que C ++ es en realidad más rápido, son programas altamente optimizados, donde los programadores expertos optimizan a fondo el código. Esto no solo consume mucho tiempo (y, por lo tanto, es costoso), sino que también conduce a errores debido a las optimizaciones excesivas.
Por otro lado, el código en los idiomas interpretados se vuelve más rápido en versiones posteriores del tiempo de ejecución (.NET CLR o Java VM), sin que usted haga nada. Y hay un montón de optimizaciones útiles que pueden hacer los compiladores JIT que son simplemente imposibles en los idiomas con punteros. Además, algunos argumentan que la recolección de basura en general debería ser tan rápida o más rápida como la administración de memoria manual, y en muchos casos lo es. En general, puede implementar y lograr todo esto en C ++ o C, pero será mucho más complicado y propenso a errores.
Como dijo Donald Knuth, "la optimización prematura es la raíz de todo mal". Si realmente sabe con certeza que su aplicación consistirá principalmente de aritmética crítica de rendimiento, y que será el cuello de botella, y ciertamente será más rápido en C ++, y está seguro de que C ++ no entrará en conflicto con el otro. requisitos, ir para C ++. En cualquier otro caso, concéntrese en implementar primero su aplicación correctamente en el idioma que más le convenga, luego encuentre cuellos de botella en el rendimiento si se ejecuta demasiado lento y luego piense cómo optimizar el código. En el peor de los casos, es posible que deba llamar al código C a través de una interfaz de función externa, por lo que aún tendrá la capacidad de escribir partes críticas en un lenguaje de nivel inferior.
Tenga en cuenta que es relativamente fácil optimizar un programa correcto, pero mucho más difícil corregir un programa optimizado.
Dar porcentajes reales de las ventajas de velocidad es imposible, depende en gran medida de su código. En muchos casos, la implementación del lenguaje de programación no es ni siquiera el cuello de botella. Tome los puntos de referencia en http://benchmarksgame.alioth.debian.org/ con mucho escepticismo, ya que estos en gran parte prueban el código aritmético, que probablemente no se parece en nada a su código.
Para gráficos, la clase de gráficos C # estándar es mucho más lenta que GDI a la que se accede a través de C / C ++. Sé que esto no tiene nada que ver con el lenguaje en sí, más con la plataforma .NET total, pero Gráficos es lo que se ofrece al desarrollador como reemplazo de GDI, y su rendimiento es tan malo que ni siquiera me atrevería a hacer gráficos con eso.
Tenemos un simple punto de referencia que utilizamos para ver qué tan rápido es una biblioteca de gráficos, y eso es simplemente dibujar líneas al azar en una ventana. C ++ / GDI sigue siendo ágil con 10000 líneas, mientras que C # / Graphics tiene dificultades para hacer 1000 en tiempo real.
Para problemas ''vergonzosamente paralelos'', al usar Intel TBB y OpenMP en C ++, he observado un aumento de rendimiento de aproximadamente 10x en comparación con problemas similares (matemáticos puros) hechos con C # y TPL. SIMD es un área donde C # no puede competir, pero también tengo la impresión de que TPL tiene una sobrecarga considerable.
Dicho esto, solo uso C ++ para tareas críticas de rendimiento en las que sé que podré multiproceder y obtener resultados rápidamente. Para todo lo demás, C # (y ocasionalmente F #) está bien.
Sé que no es lo que estabas preguntando, pero C # a menudo es más rápido de escribir que C ++, lo cual es una gran ventaja en un entorno comercial.
Supongo que hay aplicaciones escritas en C # que se ejecutan rápidamente, así como que hay más aplicaciones escritas de C ++ que se ejecutan rápidamente (bueno, C ++ es más antiguo ... y toma UNIX también ...)
- La pregunta es: ¿qué es eso, usuarios y desarrolladores se quejan de ...
Bueno, en mi humilde opinión, en el caso de C # tenemos una interfaz de usuario muy cómoda, una muy buena jerarquía de bibliotecas y todo el sistema de interfaz de CLI. En el caso de C ++, tenemos plantillas, ATL, COM, MFC y un paquete completo de código ya escrito y en ejecución como OpenGL, DirectX, etc. en un segundo - ¡bang! está atascado).
Escribir código en C # es muy simple y rápido (no se olvide que también aumenta la posibilidad de errores. En el caso de C ++, los desarrolladores se quejan de las pérdidas de memoria, lo que significa aplastamientos, llamadas entre DLL, así como "DLL hell") bibliotecas de soporte y reemplazo por otras más nuevas ...
Creo que cuantas más habilidades tengas en el lenguaje de programación, más calidad (y velocidad) caracterizará tu software.
Un escenario particular en el que C ++ todavía tiene ventaja (y lo será, durante los próximos años) ocurre cuando las decisiones polimórficas pueden predeterminarse en el momento de la compilación.
En general, la encapsulación y la toma de decisiones diferida es algo bueno porque hace que el código sea más dinámico, más fácil de adaptar a los requisitos cambiantes y más fácil de usar como marco. Esta es la razón por la que la programación orientada a objetos en C # es muy productiva y puede generalizarse bajo el término "generalización". Desafortunadamente, este tipo particular de generalización tiene un costo en tiempo de ejecución.
Por lo general, este costo no es sustancial, pero existen aplicaciones en las que la sobrecarga de las llamadas de métodos virtuales y la creación de objetos puede marcar la diferencia (especialmente porque los métodos virtuales evitan otras optimizaciones, como la integración de llamadas a métodos). Aquí es donde C ++ tiene una gran ventaja, ya que puede usar plantillas para lograr un tipo diferente de generalización que no tiene impacto en el tiempo de ejecución, pero no es necesariamente menos polimórfico que OOP. De hecho, todos los mecanismos que constituyen OOP pueden modelarse utilizando solo técnicas de plantilla y resolución en tiempo de compilación.
En tales casos (y es cierto, a menudo están restringidos a dominios de problemas especiales), C ++ gana contra C # y lenguajes similares.
> De lo que he oído ...
Su dificultad parece estar en decidir si lo que ha escuchado es creíble, y esa dificultad solo se repetirá cuando intente evaluar las respuestas en este sitio.
¿Cómo vas a decidir si las cosas que la gente dice aquí son más o menos creíbles de lo que escuchaste originalmente?
Una forma sería pedir evidencia .
Cuando alguien dice "hay algunas áreas en las que C # demuestra ser más rápido que C ++", pregúnteles por qué lo dicen , pídales que le muestren las mediciones, pídales que le muestren los programas. A veces simplemente habrán cometido un error. A veces descubrirás que solo están expresando una opinión en lugar de compartir algo que pueden demostrar que es verdad.
A menudo, la información y la opinión se mezclarán con lo que la gente afirma, y tendrás que intentar determinar cuál es cuál. Por ejemplo, de las respuestas en este foro:
"Tome los puntos de referencia en http://shootout.alioth.debian.org/ con mucho escepticismo, ya que estos en gran parte prueban el código aritmético, que probablemente no se parece en nada a su código".
Pregúntese a sí mismo si realmente entiende lo que significa "este código aritmético de prueba en gran medida" , y luego pregúntese si el autor realmente le ha demostrado que su afirmación es cierta.
"Esa es una prueba bastante inútil, ya que realmente depende de qué tan bien se hayan optimizado los programas individuales; he logrado acelerar algunos de ellos 4-6 veces o más, dejando claro que la comparación entre programas no optimizados es bastante tonto."
Pregúntese si el autor realmente le ha demostrado que ha logrado "acelerar algunos de ellos de 4 a 6 veces o más": ¡es un reclamo fácil de hacer!
> Después de todo, las respuestas tienen que estar en algún lugar, ¿no es así? :)
Umm no.
Como se indicó en varias respuestas, la pregunta está subespecificada en formas que invitan a las preguntas a responder, no respuestas. Para tomar una sola manera:
- La pregunta combina lenguaje con implementación de lenguaje. Este programa en C es 2,194 veces más lento y 1,17 veces más rápido que este programa en C # . Tendríamos que preguntarte: ¿Qué implementaciones de lenguaje?
¿Y luego qué programas? Que maquina Que sistema operativo ¿Qué conjunto de datos?
Inspirado por esto, hice una prueba rápida con el 60 por ciento de la instrucción común necesaria en la mayoría de los programas.
Aquí está el código C #:
for (int i=0; i<1000; i++)
{
StreamReader str = new StreamReader("file.csv");
StreamWriter stw = new StreamWriter("examp.csv");
string strL = "";
while((strL = str.ReadLine()) != null)
{
ArrayList al = new ArrayList();
string[] strline = strL.Split('','');
al.AddRange(strline);
foreach(string str1 in strline)
{
stw.Write(str1 + ",");
}
stw.Write("/n");
}
str.Close();
stw.Close();
}
La matriz de cadenas y el arrailista se usan a propósito para incluir esas instrucciones.
Aquí está el código c ++:
for (int i = 0; i<1000; i++)
{
std::fstream file("file.csv", ios::in);
if (!file.is_open())
{
std::cout << "File not found!/n";
return 1;
}
ofstream myfile;
myfile.open ("example.txt");
std::string csvLine;
while (std::getline(file, csvLine))
{
std::istringstream csvStream(csvLine);
std::vector csvColumn;
std::string csvElement;
while( std::getline(csvStream, csvElement, ‘,’) )
{
csvColumn.push_back(csvElement);
}
for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
{
myfile << *j << ", ";
}
csvColumn.clear();
csvElement.clear();
csvLine.clear();
myfile << "/n";
}
myfile.close();
file.close();
}
El tamaño del archivo de entrada que utilicé fue de 40 KB.
Y aquí está el resultado:
- El código de C ++ se ejecutó en 9 segundos.
- Código C #: 4 segundos !!!
Oh, pero esto estaba en Linux ... Con C # ejecutándose en Mono ... Y C ++ con g ++.
OK, esto es lo que obtuve en Windows - Visual Studio 2003 :
- El código C # se ejecutó en 9 segundos.
- Código C ++ - ¡370 segundos horribles!
Lo diría de esta manera: los programadores que escriben código más rápido, son los que están más informados de lo que hace que las máquinas actuales vayan más rápido, e incidentalmente, también son los que usan una herramienta adecuada que permite un nivel bajo y determinista precisos. Técnicas de optimización. Por estas razones, estas personas son las que usan C / C ++ en lugar de C #. Me atrevería a afirmar esto como un hecho.
Realmente depende de lo que estés tratando de lograr en tu código. He escuchado que solo es una leyenda urbana que hay alguna diferencia de rendimiento entre VB.NET, C # y C ++ administrado. Sin embargo, he encontrado, al menos en las comparaciones de cuerdas, que C ++ logró superar los pantalones de C #, que a su vez supera a los pantalones de VB.NET.
De ninguna manera he hecho comparaciones exhaustivas en la complejidad algorítmica entre los idiomas. También estoy usando la configuración predeterminada en cada uno de los idiomas. En VB.NET, estoy usando configuraciones para requerir la declaración de variables, etc. Aquí está el código que estoy usando para C ++ administrado: (Como puede ver, este código es bastante simple). Estoy ejecutando lo mismo en otros idiomas en Visual Studio 2013 con .NET 4.6.2.
#include "stdafx.h"
using namespace System;
using namespace System::Diagnostics;
bool EqualMe(String^ first, String^ second)
{
return first->Equals(second);
}
int main(array<String ^> ^args)
{
Stopwatch^ sw = gcnew Stopwatch();
sw->Start();
for (int i = 0; i < 100000; i++)
{
EqualMe(L"one", L"two");
}
sw->Stop();
Console::WriteLine(sw->ElapsedTicks);
return 0;
}
Si no me equivoco, las plantillas de C # se determinan en tiempo de ejecución. Esto debe ser más lento que las plantillas de tiempo de compilación de C ++.
Y cuando se toman todas las otras optimizaciones en tiempo de compilación mencionadas por tantos otros, así como la falta de seguridad que, de hecho, significa más velocidad ...
Yo diría que C ++ es la opción obvia en términos de velocidad bruta y consumo mínimo de memoria. Pero esto también se traduce en más tiempo para desarrollar el código y garantizar que no pierda memoria o cause ninguna excepción de puntero nulo.
Veredicto:
C #: Desarrollo más rápido, ejecución más lenta
C ++: Desarrollo lento, ejecución más rápida.