Je suppose que ce n’est pas parce qu’ils se résument tous les deux au même IL
Réponses
Trop de publicités?F# fournit certaines des fonctionnalités de performances qui peuvent faire une différence.
Tout d'abord, la mise en œuvre des délégués .NET est actuellement tout à fait inefficace et, par conséquent, F# utilise son propre FastFunc type de haute performance de première classe de fonctions. Par exemple, la règle suivante s'applique à 8 argument de la fonction d'un certain nombre de fois en F#:
do
let timer = System.Diagnostics.Stopwatch.StartNew()
let f a b c d e f g h = a+b+c+d+e+f+g+h
let mutable i = 0
for n=1 to 30000000 do
i <- i + f 1 2 3 4 5 6 7 8
printfn "%d in %fs" i timer.Elapsed.TotalSeconds
et l'équivalent en C#:
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
var timer = System.Diagnostics.Stopwatch.StartNew();
Func<int, Func<int, Func<int, Func<int, Func<int, Func<int, Func<int, Func<int, int>>>>>>>> foo =
a => b => c => d => e => f => g => h => a + b + c + d + e + f + g + h;
int i = 0;
for (int n = 1; n <= 30000000; ++n)
i += foo(1)(2)(3)(4)(5)(6)(7)(8);
Console.WriteLine(i);
Console.WriteLine(timer.Elapsed.TotalSeconds);
}
}
La compilation à la fois à l'UC sur ce processeur Intel Core i7-3610QM-à 2,3 GHZ, le F# est 65x plus rapide que son équivalent en C#.
Deuxièmement, F# utilise .NET métadonnées pour transmettre des fonctions en ligne de sorte qu'ils peuvent être exportés à travers des Api et, bien sûr, qui peut considérablement améliorer les performances dans certaines circonstances. De plus, F#'inline permet des fonctions passés comme arguments de fonctions d'ordre supérieur pour être complètement incorporé et le type spécialisé. Notre F# pour les objets Numériques [note: une licence commerciale, site détenu par l'auteur] de la bibliothèque fait un large usage de cette fonction pour vous assurer que les per-type de fonctions telles que la comparaison de la sont spécialisées. Nous avons observé les performances en F#, jusqu'à 2350 x plus rapide que son équivalent en C# (!). En fait, certains de nos routines numériques sont systématiquement plusieurs fois plus rapide que le vendeur à l'écoute Fortran dans les bibliothèques, comme les Intel MKL. Voici un exemple simple de mise en œuvre de tri à bulles en F# qui utilise inline
pour supprimer la surcharge de l' >
fonction et le générique de type tableau:
let inline bubblesort (>) (xs: _ []) =
for i=0 to xs.Length-2 do
for j=i+1 to xs.Length-1 do
if xs.[i] > xs.[j] then
let t = xs.[i]
xs.[i] <- xs.[j]
xs.[j] <- t
do
let xs = Array.init 30000 (fun i -> -float i)
let timer = System.Diagnostics.Stopwatch.StartNew()
bubblesort (>) xs
printfn "%fs for %A" timer.Elapsed.TotalSeconds xs
et voici l'équivalent en C#:
using System;
class Program
{
static void bubblesort<T>(Func<T, Func<T, bool>> greater, T[] xs)
{
for (int i=0; i<xs.Length-1; ++i)
for (int j=i+1; j<xs.Length; ++j)
if (greater(xs[i])(xs[j]))
{
var t = xs[i];
xs[i] = xs[j];
xs[j] = t;
}
}
static void Main(string[] args)
{
var xs = new double[30000];
for (int i=0; i<xs.Length; ++i)
xs[i] = -i;
var timer = System.Diagnostics.Stopwatch.StartNew();
bubblesort<double>(x => y => x>y, xs);
Console.WriteLine(timer.Elapsed.TotalSeconds);
for (int i = 0; i < 10; ++i)
Console.WriteLine(xs[i]);
}
}
F# est plus de 9 fois plus rapide que le C# ici.
Enfin, le motif correspond peut être extrêmement difficile à exprimer en C# parce que la langue manque de correspondance de motif, mais il est presque impossible de maintenir optimisé le code C# équivalent à beaucoup de non-trivial modèle correspond. En revanche, le compilateur F# agressivement optimise les correspondances de modèle lors de la compilation.
A l'inverse, le compilateur C# peut-être encore mieux à l'optimisation des calculs sur des types de valeur (par exemple complexe arithmétique) et a "goto" qui peut être plus efficace que n'importe quoi actuellement disponible en F#.
Pour un large éventail de programmes, un code similaire dans les deux langues devraient présenter les mêmes caractéristiques de performance; c'est un objectif pour F# avoir les mêmes perf sur le semblable code des comparaisons. Simplement transliterating de code C# F# ou vice-versa devrait avoir presque aucun effet.
Comme mentionné par d'autres, certaines F# structures de données et les expressions idiomatiques peuvent négocier certains perf pour d'autres prestations. Mais c'est votre choix; F# perfomance méthodologie embrasse la programmation impérative lorsqu'il vous net des avantages mesurables, donc si vous avez besoin d'utiliser beaucoup de tableaux et des boucles d'aller pour elle.
F# offre une excellente affaire pour le calcul de haute performance, notamment des fonctionnalités de langage comme async flux de travail (qui le rendent facile à paralléliser le code ou de profiter de plusieurs Processeurs) et une préférence générale pour l'immutabilité (ce qui peut rendre le code multithread moins d'erreurs).
Enfin, bien qu'un peu en dehors de la portée de la question (ce qui demande une comparaison entre les deux), n'oubliez pas que dans le monde réel, vous n'avez toujours pas de choisir l'un ou l'autre. Un certain nombre d'applications ont été écrits avec un mélange de F# et C#; l'interopérabilité entre les deux langues est très simple, et il est souvent judicieux de l'auteur d'une partie d'une grande application dans une langue et une autre partie dans l'autre, afin de profiter des avantages de leurs forces.
Vous pouvez probablement écrire du code dans un langage de compilation de presque exactement la même CLR bytecode.
La question importante est de savoir si idiomatiques F# sera plus efficace que idiomatiques C#.
Par exemple, les langages de programmation fonctionnelle ont tendance à favoriser l'usage de immuable structures de données (certains, mais pas de F#, même le demander). Bien que ces structures de données peuvent être plus efficaces que leurs naïfs implémentations (ce qui impliquerait beaucoup de clonage), mutable structures de données intrinsèquement donner plus de liberté au programmeur, et peut donc être plus efficace.
Cela étant dit, il y a un argument théorique que l'immuabilité est mieux adapté à l'exploitation des processeurs multi-core et parallélisme en général. Je ne suis pas au courant de la recherche qui le prouve bien.
La ligne de fond est qu'il n'y a pas de réponse simple, mais généralement bien écrit F# sera probablement plus lent, car il accorde une plus grande priorité sur le respect de la programmation fonctionnelle, de l'idéologie, qui donne priorité à l'élégance aux dépens de l'efficacité.
Je dirais que cela dépend de ce que "l'efficacité" sommes-nous en train de parler. Je pense que dans la plupart des cas, le code final (IL) va être très similaire. D'autre part l'efficacité de vous, en tant que développeur, peuvent être différentes. Il y a certains problèmes qui sont plus facilement décrits et mis en œuvre à l'aide d'un langage fonctionnel et dans ces cas, le code sera plus facile à l'écrit et maintenu à l'aide d'un langage fonctionnel.
Personnellement, je vois la puissance de F# dans le fait que parce qu'il est construit sur CLR vous pouvez mélanger F# et C# pour décrire les différentes parties de vos applications dans un langage différent (vous utilisez celui qui est le plus adapté).
PS: Le même est vrai pour les langages dynamiques. Je ne pense pas qu'ils sont beaucoup mieux que les langages tels que C#, mais pour certains types de programmation, vous pourriez vous sentir plus productif.