tabla que programacion mismo mejor lenguajes lenguaje entre diferencias diferencia cyc comparacion c++ c performance np-hard

que - Necesito un alto rendimiento. ¿Habrá una diferencia si uso C o C++?



lenguaje c (14)

Buenas respuestas Yo lo pondría así:

  1. Haga que el algoritmo sea lo más eficiente posible en términos de su estructura formal.

  2. C ++ será tan rápido como C, excepto que te tentará a hacer cosas tontas, como construir objetos que no tienes que hacer, así que no mientas. Cosas como las clases de contenedor de STL y los iteradores pueden parecer lo último y lo mejor, pero te matarán en un punto de acceso.

  3. Aun así, en un solo paso en el nivel de desmontaje. Deberías verlo trabajando directamente en tu problema. Si está gastando muchos ciclos entrando y saliendo de las rutinas, intente algo de alineación (o macros). Si está deambulando en la asignación de memoria y liberando, durante gran parte del tiempo, deténgalo. Si tiene bucles internos en los que la sobrecarga del bucle es un porcentaje grande, intente desenrollar el bucle.

Así es como puedes hacerlo lo más rápido posible.

Necesito escribir un programa (un proyecto para la universidad) que resuelva (aproximadamente) un problema de NP-difícil. Es una variación de los problemas de ordenamiento lineal. En general, tendré insumos muy grandes (como Gráficos) e intentaré encontrar la mejor solución (basada en una función que "clasifique" cada solución)

¿Habrá una diferencia si escribo esto en el código de estilo C (uno principal y funciones) o construyo una clase de Solver, creo una instancia e invoco un método ''ejecutar'' desde un main (similar a Java)

Además, habrá una gran cantidad de matemáticas de punto flotante en cada iteración.

¡Gracias!


Cuando se habla de rendimiento, cualquier cosa que pueda hacer en C puede hacerse en C ++. Por ejemplo, se sabe que los métodos virtuales son "lentos", pero si realmente es un problema, aún puede recurrir a los idiomas.

C ++ también trae plantillas, lo que lleva a un mejor rendimiento que el uso de void* para la programación genérica.


Dado que ambos están compilados, y los compiladores ahora son muy buenos en cómo manejar C ++, creo que el único problema provendría de qué tan bien optimizado esté su código. Creo que sería más fácil escribir código más lento en C ++, pero eso depende del estilo en el que su modelo se adapte mejor.

Cuando se llega a esto, dudo que haya alguna diferencia real, asumiendo que ambos están bien escritos, las bibliotecas que usa, lo bien que están escritas, si está midiendo en la misma computadora.


El mayor obstáculo para el código óptimo ya no es el lenguaje (para los lenguajes compilados correctamente), sino el programador.


Es improbable que la sobrecarga de llamada de función contra función de miembro sea el factor limitante, en comparación con la entrada de archivos y el algoritmo en sí. Los iostreams de C ++ no son necesariamente súper alta velocidad. C tiene ''restringir'' si realmente está optimizando, en C ++ es más fácil hacer llamadas de función en línea. En general, C ++ ofrece más opciones para organizar su código claramente, pero si no es un programa grande, o simplemente lo escribirá de manera similar si es C o C ++, entonces la portabilidad de las bibliotecas de C se vuelve más importante.


Hago algunos códigos DSP, donde todavía vale la pena ir a lenguaje ensamblador a veces. Yo diría que use C o C ++, cualquiera de los dos, y que esté preparado para utilizar el lenguaje ensamblador cuando lo necesite, especialmente para explotar las instrucciones SIMD.


La clase de Solver se construirá una vez, lo tomo, y el método de run se ejecuta una vez ... en ese tipo de entorno, no verás una diferencia. En cambio, aquí hay cosas a tener en cuenta:

  • La gestión de la memoria es tremendamente cara. Si necesita hacer un montón de pequeños malloc() s malloc() , el sistema operativo se comerá su almuerzo. Haga un esfuerzo decidido por reutilizar las estructuras de datos que cree si sabe que pronto volverá a hacer lo mismo.

  • Instalar clases generalmente significa ... ¡asignar memoria! Nuevamente, prácticamente no hay costo para crear una instancia de un puñado de objetos y reutilizarlos. ¡Pero ten cuidado de crear objetos solo para derribarlos y reconstruirlos poco después!

  • Elija el sabor correcto de punto flotante para su arquitectura, en la medida en que el problema lo permita. Es posible que el double termine siendo más rápido que el float , aunque necesitará más memoria. Debes experimentar para afinar esto. Idealmente, #define o typedef para especificar el tipo para que puedas cambiarlo fácilmente en un solo lugar.

  • Los cálculos de enteros son probablemente más rápidos que el punto flotante. Dependiendo del rango numérico de sus datos, también puede considerar hacerlo con enteros tratados como decimales de punto fijo. Si necesita 3 lugares decimales, puede usar int s y simplemente considerarlos como "mili algo". Tendrá que recordar cambiar los decimales después de la división y la multiplicación ... pero no es gran cosa. Si utiliza alguna función matemática más allá de la aritmética básica, por supuesto, eso eliminaría esta posibilidad.


Mientras no use ninguna función virtual, etc., no notará ninguna diferencia de rendimiento considerable. Early C ++ se compiló en C, por lo que siempre que conozca los puntos clave en los que esto genere una sobrecarga considerable (como las funciones virtuales), podrá calcular claramente las diferencias.

Además, quiero señalar que usar C ++ puede darte mucho que ganar si usas las bibliotecas STL y Boost. Especialmente, el STL proporciona implementaciones muy eficientes y probadas de las estructuras de datos y algoritmos más importantes, para que pueda ahorrar mucho tiempo de desarrollo.

Efectivamente, también depende del compilador que usará y de cómo optimizará el código.


No, a menos que esté utilizando funciones virtuales.

Edición: Si tiene un caso en el que necesita dinamismo en tiempo de ejecución, entonces sí, las funciones virtuales son tan rápidas o más rápidas que una instrucción if-else construida manualmente. Sin embargo, si coloca la palabra clave virtual delante de un método, pero en realidad no necesita el polimorfismo, tendrá que pagar un costo innecesario. El compilador no lo optimizará lejos en tiempo de compilación. Solo lo señalo porque es una de las características de C ++ que rompe el "principio de sobrecarga cero" (que cita a Stroustrup).

Como nota al margen, ya que mencionas el uso intensivo de fp math:

  • Los siguientes indicadores de gcc pueden ayudarlo a acelerar las cosas (estoy seguro de que hay equivalentes para C ++ visual, pero no lo uso): -mfpmath=sse , -ffast-math y -mrecip (los dos últimos son '' ligeramente peligroso ", lo que significa que podrían darte resultados extraños en casos de borde a cambio de la velocidad. El primero reduce la precisión en un bit (tienes dobles de 64 bits en lugar de 80 bits), pero esta precisión adicional es a menudo innecesarios.) Estas banderas funcionarían igual de bien para los compiladores C y C ++.
  • Dependiendo de su procesador, también puede encontrar que simular un verdadero INFINITY con un valor grande pero no infinito le da un buen impulso de velocidad. Esto se debe a que el procesador debe manejar la verdadera INFINITY como un caso especial.

  • No.

    Las mayores ganancias / fallas de rendimiento estarán en el algoritmo que implementes, y la cantidad de trabajo innecesario que realices (el trabajo innecesario puede ser todo, desde recalcular un valor anterior que podría haberse almacenado en la caché, hasta el uso de demasiados recursos de malloc / free usando pools de memoria, pasando grandes datos inmutables por valor en lugar de referencia)


    Otro aspecto:

    Las plantillas de C ++ pueden ser una excelente herramienta para generar variaciones de código optimizadas / específicas del tipo.

    Por ejemplo, C qsort requiere una llamada de función al comparador, mientras que std::sort puede integrar el funtor pasado. Esto puede hacer una diferencia significativa cuando las comparaciones y los intercambios son baratos.

    Tenga en cuenta que podría generar "preguntas personalizadas" optimizadas para varios tipos con un aluvión de definiciones o un generador de códigos, o manualmente, también podría hacer estas optimizaciones en C, pero a un costo mucho mayor.

    (No es un arma general, las plantillas solo ayudan en escenarios específicos, generalmente un solo algoritmo aplicado a diferentes tipos de datos o con diferentes piezas de código inyectadas).


    Primero, escribir en C ++ no implica el uso de OOP, mire los algoritmos STL. en segundo lugar, C ++ puede ser incluso un poco más rápido en tiempo de ejecución (los tiempos de compilación pueden ser terribles en comparación con C, pero eso se debe a que C ++ moderno depende en gran medida de las abstracciones que afectan al compilador).

    edit : está bien, vea la discusión de Qjarort y std :: sort de Bjarne Stroustrup, y el artículo que menciona en las Preguntas frecuentes ( Learning Standard C ++ como un nuevo idioma ), donde muestra que el código de estilo C ++ no solo puede ser más corto y más legible (porque de abstracciones superiores), pero también algo más rápido.


    Regla de oro: no optimice hasta que sepa qué optimizar. Así que empieza con C ++ y ten un prototipo funcional. Luego, perfílelo y reescriba los cuellos de botella en el ensamblaje. Pero como otros lo señalaron, el algoritmo elegido tendrá un impacto mucho mayor que el lenguaje.


    Yo iría con C ++ definitivamente. Si tiene cuidado con su diseño y evita crear objetos pesados ​​dentro de puntos de acceso, no debería ver ninguna diferencia de rendimiento, pero el código será mucho más sencillo de entender, mantener y expandir.

    Usa plantillas y clases con criterio. Evite la creación innecesaria de objetos pasando objetos por referencia. Evite la asignación excesiva de memoria, si es necesario, asigne la memoria antes de los hotspots. Use la palabra clave de restricción en los punteros de memoria para indicar al compilador cuando los punteros se superponen o no.

    En cuanto a la optimización, preste especial atención a la alineación de la memoria. Suponiendo que está trabajando en el procesador Intel, puede utilizar instrucciones vectoriales, siempre que informe al compilador a través de pragma acerca de la alineación de la memoria y los punteros de alias. También puede utilizar instrucciones vectoriales directamente a través de intrínsecos.

    También puede crear automáticamente un código de punto de acceso usando plantillas y dejar que el compilador lo optimice si tiene cosas como bucles cortos de diferentes tamaños. Para conocer el rendimiento y profundizar en sus cuellos de botella, Intel vtune u oprofile son extremadamente útiles.

    Espero que ayude