C # / F # Comparación de rendimiento

¿Hay alguna comparación de rendimiento C # / F # disponible en la web para mostrar el uso correcto del nuevo lenguaje F #?

El código F # natural (por ejemplo, funcional / inmutable) es más lento que el código C # natural (imperativo / mutable orientado a objetos). Sin embargo, este tipo de F # es mucho más corto que el código C # habitual. Obviamente, hay una compensación.

Por otro lado, puede, en la mayoría de los casos, lograr el rendimiento del código F # igual al rendimiento del código C #. Por lo general, esto requerirá la encoding en estilo imperativo o mutable orientado a objetos, el perfil y eliminar los cuellos de botella. Usas las mismas herramientas que utilizarías en C #: por ejemplo, un reflector .Net y un generador de perfiles.

Habiendo dicho eso, vale la pena tener en cuenta algunas construcciones de alta productividad en F # que disminuyen el rendimiento. En mi experiencia, he visto los siguientes casos:

  • referencias (frente a variables de instancia de clase), solo en código ejecutado miles de millones de veces

  • Comparación de F # (<=) vs. System.Collections.Generic.Comparer, por ejemplo en búsqueda binaria u ordenación

  • llamadas de cola – solo en ciertos casos que no pueden ser optimizados por el comstackdor o el tiempo de ejecución .Net. Como se señala en los comentarios, depende del tiempo de ejecución de .Net.

  • Las secuencias F # son dos veces más lentas que LINQ. Esto se debe a las referencias y al uso de funciones en la biblioteca F # para implementar la traducción de seq <_>. Esto es fácilmente reparable, ya que puede reemplazar el módulo Seq por uno con las mismas firmas que usa Linq, PLinq o DryadLinq.

  • Tuples, F # tuple es una clase ordenada en el montón. En algunos casos, por ejemplo, una int * int tuple, podría ser útil usar una estructura.

  • Asignaciones, vale la pena recordar que un cierre es una clase, creada con el nuevo operador, que recuerda las variables accedidas. Podría valer la pena “levantar” el cierre o reemplazarlo con una función que tome explícitamente las variables accedidas como argumentos.

  • Intente usar en línea para mejorar el rendimiento, especialmente para el código genérico.

Mi experiencia es codificar en F # primero y optimizar solo las partes que importan. En ciertos casos, podría ser más fácil escribir las funciones lentas en C # en lugar de intentar ajustar F #. Sin embargo, desde el punto de vista de la eficiencia del progtwigdor, tiene sentido comenzar / prototipar en F #, luego perfilar, desmontar y optimizar.

En pocas palabras, su código F # podría terminar más lento que C # debido a las decisiones de diseño del progtwig, pero en última instancia, puede obtenerse la eficiencia.

Vea estas preguntas que hice recientemente:

  • ¿Es un progtwig F # más eficiente (en la ejecución) que C #?
  • ¿Cómo puedo usar la progtwigción funcional en el mundo real?
  • ¿Es posible que F # se optimice más que otros lenguajes .Net en el futuro?

Aquí hay algunos enlaces sobre (o relacionados con) este tema:

Lo que parece recordar de otra publicación en el blog de Robert Pickering (¿o fue Scott Hanselman?) Que al final, debido a que ambos están sentados en el mismo marco, puede obtener el mismo rendimiento de ambos, pero a veces tiene que ‘torcerse’. ‘la expresión natural del lenguaje para hacerlo. En el ejemplo que recuerdo, tuvo que girar F # para obtener un rendimiento comparable con C # …