Les expressions compilées fonctionnent beaucoup plus lentement que les versions interprétées
-
12-11-2019 - |
Question
J'ai un moteur de règles, qui prend en charge deux modes d'opérations:
- Compilation dans un programme C # et lié au moteur
- Analyser les instructions basées sur une pile de polotish et interprété
Les règles sont des expressions arithmétiques simples avec des appels de fonction (Max, Min, Sin, Cos, etc.)
J'aurais supposé que la version compilée (c'est-à-dire # 1) beaucoup Plus rapide que la version interprétée (IE # 2) - en fait, c'est la principale raison d'avoir un mode compilé en premier lieu. Cependant, mes tests de vitesse ont montré le contraire.
Version compilée
Action<double>[] Rules = new[] { calc1, calc2, calc3 ... };
double[] v = new double[...]; // Variables
void calc1(double arg) { v[3]=v[12]+v[15]/v[20] }; // "x3=x12+x15/x20"
void calc2(double arg) { ... };
:
// Start timer now
Rules.AsParallel().ForAll(r => r(...));
// End timer
Version interprétée
Expression[] Rules = ...
// Each rule is already parsed into an Expression object, which is a set of
// reverse-polish stack-based instructions.
// For example, "x3=x12+x15/x20" will be parsed to:
// [ Push(12), Push(15), Push(20), Divide(), Add() ]
// Start timer now
Rules.AsParallel().ForAll(r => r.Evaluate(...));
// End timer
Ici, "Expression" fait partie d'une bibliothèque tierce qui analyse une chaîne simple dans un simple ensemble d'instructions basées sur des piles de pololish, qui peuvent ensuite être interprétées. Il est ne pas L'objet d'expression-arbre dans LINQ - juste pour clarification.
Remarque: ne vous inquiétez pas de la concurrence car dans le code réel, je trierai les règles par "couches" et calcule les couches séquentiellement, dont chaque couche uniquement en fonction des valeurs calculées dans les couches précédentes. Les deux modes ont exactement la même structure de couches.
Les résultats
Étonnamment, la version interprétée fonctionne BEAUCOUP Plus rapide que la version compilée, en moyenne un facteur de 4x! En d'autres termes, la version compilée a pris 0,3 s pour parcourir environ 1 200 règles, tandis que la version interprétée a pris en moyenne 0,08-0,1 s.
Mon ordinateur est un core-core / so dual2.
J'utilise .NET 4.0, Visual Studio 10.
Les performances sont similaires dans les versions de débogage ou de version.
Ma question
Qu'est-ce qui peut provoquer le ralentissement significatif du mode compilé?
Remarque: j'ai posté une réponse possible
Pas de solution correcte