Les expressions compilées fonctionnent beaucoup plus lentement que les versions interprétées

StackOverflow https://stackoverflow.com/questions/5963649

Question

J'ai un moteur de règles, qui prend en charge deux modes d'opérations:

  1. Compilation dans un programme C # et lié au moteur
  2. 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top