Pregunta

¿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 de probarlo por mí mismo.

Pensé que cualquiera de ustedes podría explicar estas diferencias en detalle o indicarme el lugar correcto para obtener información sobre esto.

¿Fue útil?

Solució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 JIT más avanzadas son complicadas de implementar, y las realmente geniales están llegando ahora mismo.

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 otra parte, 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, puedes 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 de 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 ni siquiera es el cuello de botella. Tome los puntos de referencia en http://benchmarksgame.alioth.debian.org/ con mucho escepticismo , ya que en gran parte prueban el código aritmético, que probablemente no se parece en nada a su código.

Otros consejos

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. :)

Es cinco naranjas más rápido. O más bien: no puede haber una respuesta general (correcta). C ++ es un lenguaje estáticamente compilado (pero también está la optimización guiada por perfil), C # funciona con la ayuda de un compilador JIT. Hay tantas diferencias que preguntas como & # 8220; cuánto más rápido & # 8221; no se puede responder, ni siquiera dando órdenes de magnitud.

Comenzaré por no estar de acuerdo con 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 C ++ correctamente optimizado (u otro idioma sin sobrecarga de tiempo de ejecución) programa incluyendo:

  • los ciclos de cómputo gastados en el código JITting en tiempo de ejecución no están disponibles por definición 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 idiomas nativos como C ++ no tienen este tipo de contención, por definición.

  • el presupuesto de tiempo de un 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, probablemente será capaz de 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 determinar la diferencia en el rendimiento y luego decidir si vale la pena el esfuerzo y la complejidad adicionales.

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 que es capaz de realizar ciertas optimizaciones dinámicas en tiempo de ejecución que simplemente no están disponibles para C ++ con su compilación Optimizador de tiempo (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 de la " casi ciertamente " calificador 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 afirmaciones 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 ++ idiomático más 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 utilizado :: 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, Fill: 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

Tiempo total de ejecución: C #: 289ms, C ++ 152ms (aproximadamente un 90% más rápido)

Observations

  • Cambiando la implementación de C # a la misma implementación de matriz 1d produjo Inicial: 40 ms, Relleno: 171 ms, total: 211 ms ( C ++ todavía era casi 40% más rápido ).

  • Es mucho más difícil diseñar y escribir " rápido " Código en C ++ de lo que es escribir " regular " código en cualquier idioma.

  • Es (quizás) sorprendentemente fácil obtener un bajo rendimiento en C ++; Lo vimos con un rendimiento de vectores sin reservas. Y hay muchos escollos como este.

  • 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 acceso.

  • 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, llegar a tomar todas estas opciones (y más) usted mismo, idealmente para que su solución resuelva 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.

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 finalmente 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.

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 & # 8220; generalization & # 8221 ;. Desafortunadamente, este tipo particular de generalización tiene un costo en tiempo de ejecución.

Por lo general, este costo no es sustancial, pero hay aplicaciones en las que la sobrecarga de las llamadas a los 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 los métodos). Aquí es donde C ++ tiene una gran ventaja porque puede usar plantillas para lograr un tipo diferente de generalización que tiene no en el tiempo de ejecución, pero no es necesariamente menos polimórfica que la POO. De hecho, todos los mecanismos que constituyen OOP se pueden modelar 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 # e idiomas similares.

C ++ (o C en este caso) le brinda un control preciso sobre sus estructuras de datos. Si quieres hacer twinsdle, tienes esa opción. Grandes aplicaciones administradas de Java o .NET (OWB, Visual & nbsp; Studio & nbsp; 2005 ) que utilizan el las estructuras de datos internas de las bibliotecas de Java / .NET llevan el equipaje con ellas. He visto sesiones de diseño de OWB utilizando más de 400 MB de RAM y BIDS para cubo o ETL el diseño se está introduciendo también en 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 obtener el 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 en sí. 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 ganan es donde puede optimizar el uso de las estructuras de datos para jugar bien con el caché de la CPU.

Para gráficos, la clase estándar de gráficos C # 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 un reemplazo GDI, y su rendimiento es tan malo que ni siquiera me atrevería a hacer gráficos con ello.

Tenemos un simple punto de referencia que usamos 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.

La recolección de basura es la razón principal por la que Java # NO SE PUEDE usar para sistemas en tiempo real.

  1. ¿Cuándo sucederá el GC?

  2. ¿Cuánto tiempo tomará?

Esto no es determinista.

Hemos tenido que determinar si C # era comparable al rendimiento de C ++ 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 datos aumentan más allá de los límites de la línea de caché. Sin embargo, todo esto tuvo que pagarse finalmente y hay un costo enorme en forma de resultados de rendimiento no deterministas para C # debido a la recolección de basura.

Como de costumbre, depende de la aplicación. Hay casos en los que C # es probablemente más lento, y otros casos en los que C ++ es 5 o 10 veces más rápido, especialmente en casos donde las operaciones se pueden SIMD'd fácilmente.

Sé que no es lo que estaba preguntando, pero C # es a menudo escribir más rápido que C ++, lo que es una gran ventaja en un entorno comercial.

C / C ++ puede funcionar mucho mejor en programas donde hay arreglos grandes o bucles pesados ??/ iteración 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 Boost, std :: vector y otros contenedores de alto nivel, así como inline cada pequeña función posible. 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 la declaración correspondiente de delete [] (o use std: : unique_ptr ) & # 8212; el precio por 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 tanto en Java como .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 de puntero en bruto de C ++ llegó aproximadamente 2.1x más rápido que C # . Tenga en cuenta que el programa C # solo usó el código de seguridad & # 8212; es mi opinión de que también puede 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. 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? 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 aún no hayan hecho tantas cosas en el lenguaje C #, ¿por qué no seguirlo con optimizaciones de compiladores? Tal vez si todos rogamos.

> Por lo que he oído ...

Su dificultad parece estar en decidir si lo que escuchó 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 solicitar pruebas .

Cuando alguien dice " hay algunas áreas en las que C # demuestra ser más rápido que C ++ " pregúnteles por qué dicen eso , pídales que le muestren medidas, pídales que le muestren 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 mezclan 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, como estos en gran parte prueba código aritmético, que es muy probable que no es similar a su código en absoluto. "

    Pregúntate a ti mismo si realmente Entender lo que " estas pruebas en gran medida código aritmético " significa, y luego pregúntate si el autor tiene En realidad te mostró que su reclamo es verdadero.

  • " Esa es una prueba bastante inútil, ya que realmente depende de qué tan bien los programas individuales han sido optimizado Me las arreglé para acelerar algunos de ellos por 4-6 veces o más, dejando claro que la comparación entre los programas no optimizados es bastante tonto. "

    Pregúntate si el autor tiene En realidad te mostró que él ha logrado para " acelerar algunos de ellos por 4-6 veces o más " - ¡Es un reclamo fácil de hacer!

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 sobre sus pausas.

Entonces, 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.

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ática pura) realizados 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é multiprocilar y obtener resultados rápidamente. Para todo lo demás, C # (y ocasionalmente F #) está bien.

Es una pregunta extremadamente vaga sin respuestas definitivas reales.

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 mucho a la realidad).

Por otro lado, como se mencionó anteriormente; debe desarrollarse en un lenguaje que le permita hacer lo que quiere rápidamente y luego, si es necesario, optimizar.

En teoría, para una aplicación de tipo servidor de larga ejecución, un lenguaje compilado por JIT puede ser mucho más rápido que un homólogo compilado de forma nativa. Como el lenguaje compilado JIT generalmente se compila primero en un lenguaje intermedio de nivel bastante bajo, puede hacer muchas de las optimizaciones de alto nivel justo en el momento de la compilación. 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 dedicar más esfuerzo a optimizar los bucles internos.

Dudo que esto sea hecho por .NET o cualquiera de los JRE, pero estaba siendo investigado cuando estaba en la universidad, así que no es irrazonable pensar que este tipo de cosas pueden encontrar su camino hacia el mundo real en algún punto pronto.

Aplicaciones que requieren acceso intensivo a la memoria, por ejemplo. la manipulación de imágenes suele estar mejor escrita en un entorno no administrado (C ++) que administrado (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 no seguro para incluso acercarse al mismo rendimiento.

He probado vector en C ++ y C # equivalente - 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 P8600@2.4GHz, C # - .NET 4.0.

Sé que la implementación de vectores es diferente a 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 vectorial 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 # - array:

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);

}

Hora: (Lanzamiento / Depuración)

C++

  • 600/606 ms array init,
  • Relleno de matriz de 200/270 ms,
  • 1sec / 13sec vector init & amp; llenar.

(Sí, 13 segundos, siempre tengo problemas con listas / vectores en modo de depuración).

C#:

  • 20/20 ms array init,
  • relleno de matriz de 403/440 ms,
  • 710/742 ms de la lista init & amp; llenar.

Bueno, depende. Si el código de byte 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 GC El algoritmo solo necesita un pase (teóricamente) a través de toda la memoria una vez, pero malloc normal Las llamadas de / realloc / free C / C ++ causan una sobrecarga en cada llamada (sobrecarga de llamadas, sobrecarga de la estructura de datos, falta de caché;)).

Teóricamente es posible (también para otros idiomas de GC).

Realmente no veo la desventaja extrema de no poder usar 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 el LINQ " extensión " ;, proporciona 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í).

Supongo que hay aplicaciones escritas en C # que se ejecutan rápidamente, así como hay más aplicaciones escritas de C ++ que se ejecutan rápidamente (bueno, C ++ es más antiguo ... y también toma UNIX ...)
- La pregunta es: ¿qué es eso, los usuarios y los 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 y así sucesivamente ... en un segundo - ¡bang! está atascado).
Escribir código en C # es muy simple y rápido (sin olvidar 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 interferencias, llamadas entre DLL, así como de " DLL hell " - problema con las bibliotecas de soporte y reemplazo por las nuevas ...
Creo que cuanto más habilidad tengas en el lenguaje de programación, más calidad (y velocidad) caracterizará tu software.

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 una baja precisión. Técnicas de optimización determinista y de nivel. Por estas razones, estas personas son las que usan C / C ++ en lugar de C #. Me atrevería a afirmar esto como un hecho.

> 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 de manera que invite a las preguntas a responder, no a las respuestas. Para tomar una sola manera:

¿Y luego qué programas? Que maquina Que sistema operativo ¿Qué conjunto de datos?

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 incorporas 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.

Realmente depende de lo que intentas 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 comparaciones de cadenas, 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 administrar C ++: (Como puede ver, este código es bastante simple). Estoy ejecutando lo mismo en los 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;
}

Hay algunas diferencias importantes entre C # y C ++ en el aspecto de rendimiento:

  • C # está basado en GC / heap. La asignación y el GC en sí son gastos generales como la no localidad de acceso a la memoria
  • Los optimizadores de C ++ se han vuelto muy buenos a lo largo de los años. Los compiladores JIT no pueden alcanzar el mismo nivel ya que solo tienen un tiempo de compilación limitado y no ven el alcance global

Además de eso, la competencia del programador también desempeña un papel. He visto un código de C ++ incorrecto en el que las clases pasaron por valor como argumento en todo el lugar. Realmente puedes empeorarlo en C ++ si no prestas atención.

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 & nbsp; KB.

Y aquí está el resultado -

  • El código 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 ++.

Bien, esto es lo que obtuve en Windows - Visual & nbsp; Studio & nbsp; 2003 :

  • El código C # se ejecutó en 9 segundos.
  • Código C ++ - ¡370 segundos horribles!
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top