web-dev-qa-db-fra.com

Comparaison des performances C # / F #

Existe-t-il une comparaison des performances C #/F # disponible sur le Web pour montrer l'utilisation correcte du nouveau langage F #?

54
Vijesh VP

Le code F # naturel (par exemple fonctionnel/immuable) est plus lent que le code C # naturel (impératif/mutable orienté objet). Cependant, ce type de F # est beaucoup plus court que le code C # habituel. De toute évidence, il y a un compromis.

D'un autre côté, vous pouvez, dans la plupart des cas, obtenir des performances de code F # égales aux performances de code C #. Cela nécessitera généralement un codage dans un style orienté objet impératif ou modifiable, un profil et supprimera les goulots d'étranglement. Vous utilisez les mêmes outils que vous utiliseriez autrement en C #: par exemple Réflecteur .Net et profileur.

Cela dit, il vaut la peine de connaître certaines constructions à haute productivité en F # qui diminuent les performances. D'après mon expérience, j'ai vu les cas suivants:

  • références (vs variables d'instance de classe), uniquement dans le code exécuté des milliards de fois

  • Comparaison F # (<=) vs System.Collections.Generic.Comparer, par exemple dans la recherche ou le tri binaire

  • appels de queue - uniquement dans certains cas qui ne peuvent pas être optimisés par le compilateur ou le runtime .Net. Comme indiqué dans les commentaires, dépend du runtime .Net.

  • Les séquences F # sont deux fois plus lentes que LINQ. Cela est dû aux références et à l'utilisation de fonctions dans la bibliothèque F # pour implémenter la traduction de seq <_>. Ceci est facilement réparable, car vous pourriez remplacer le module Seq, par un avec les mêmes signatures qui utilisent Linq, PLinq ou DryadLinq.

  • Tuples, F # Tuple est une classe triée sur le tas. Dans certains cas, par exemple un int * int Tuple, il pourrait être avantageux d'utiliser une structure.

  • Allocations, il convient de rappeler qu'une fermeture est une classe, créée avec le nouvel opérateur, qui se souvient des variables consultées. Il pourrait être utile de "lever" la fermeture ou de la remplacer par une fonction qui prend explicitement les variables accédées comme arguments.

  • Essayez d'utiliser en ligne pour améliorer les performances, en particulier pour le code générique.

Mon expérience consiste à coder en F # en premier et à n'optimiser que les parties importantes. Dans certains cas, il pourrait être plus facile d'écrire les fonctions lentes en C # plutôt que d'essayer de Tweak F #. Cependant, du point de vue de l'efficacité du programmeur, il est logique de démarrer/prototyper en F # puis de profiler, de démonter et d'optimiser.

En fin de compte, votre code F # pourrait finir plus lentement que C # en raison des décisions de conception de programme, mais en fin de compte, l'efficacité peut être obtenue.

53
Stefan Savev
24
Brian R. Bondy

Voici quelques liens sur (ou liés à) ce sujet:

Ce que je me souviens d'un autre article sur le blog de Robert Pickering (ou était-ce Scott Hanselman?) Qu'en fin de compte, parce que les deux sont assis sur le même cadre, vous pouvez obtenez les mêmes performances des deux, mais vous devez parfois "tordre" l'expression naturelle de la langue pour le faire. Dans l'exemple dont je me souviens, il a dû tordre F # pour obtenir des performances comparables à C # ...

11
Benjol