2011-05-24 3 views
3

dans cette question Why is this F# code so slow?, il est discuté que la comparaison structrual rend la fonction let min3(a, b, c) = min a (min b c) lente; La comparaison structruelle sur le type simple ne devrait-elle pas être aussi rapide que la comparaison native? Je suis confus parce que les gens ont parlé de toujours utiliser HashIdentity.Structural pour le dictionnaire en F # dans FSharp runs my algorithm slower than Python. Si j'ai un dictionnaire avec un type simple (int ou string) comme clé, est-ce que j'obtiens une pénalité de performance pour utiliser HashIdentity.Structural?F # type simple et comparaison structurelle

Répondre

3

De manière générale, je ne m'inquiéterais pas de la performance des comparaisons, car pour les comparaisons de code typiques, il est très peu probable qu'il y ait un goulot d'étranglement au niveau des performances. Si vous avez déterminé que vous avez un problème de performance et que le profilage révèle que les comparaisons en sont la cause, vous pouvez alors réfléchir à la meilleure façon d'y remédier.

Si vous devez prendre en compte les performances des comparaisons, vous devrez peut-être comprendre le fonctionnement du compilateur. Dans le premier exemple que vous avez cité, la fonction min3 a le type 'a * 'a * 'a -> 'a when 'a : comparison. Cette fonction sera compilée à une méthode .NET prenant 3 arguments d'un type générique qui ressemblerait à quelque chose comme ça en C#:

using LP = Microsoft.FSharp.Core.LanguagePrimitives; 

T min3<T>(T a, T b, T c) { 
    T d = LP.HashCompare.GenericLessThanIntrinsic(b,c) ? b : c; 
    return LP.HashCompare.GenericLessThanIntrinsic(d,a) ? d : a; 
} 

La méthode GenericLessThanIntrinsic est générique, et en son sein, il doit être logique pour effectuer la comparaison basée sur le type réel comparé. Cela peut nécessiter quelques tests de type et des appels de méthode virtuelle. Ce ne sont pas des opérations extrêmement coûteuses, mais elles sont considérablement plus lentes que d'effectuer une comparaison directe de deux valeurs entières. Par conséquent, si les comparaisons représentent une grande partie de votre charge de travail, l'utilisation des routines de comparaison génériques pourrait avoir un impact important sur vos performances globales et la spécialisation de la fonction min3 sur des entiers plutôt que sur des valeurs génériques .

De même, si vous êtes stocker des entiers comme clés du dictionnaire, puis en utilisant le construit en GetHashCode() et Equals() mises en œuvre sur les touches (qui est ce que le dictionnaire fera par défaut) sera plus rapide que d'utiliser la comparaison structurelle. Cependant, si cela sera une différence importante pour vous dépendra du code que vous écrivez - comme je l'ai déjà dit, il est quelque peu inhabituel pour les comparaisons clés de prendre une fraction significative du temps de fonctionnement d'un algorithme.