Domanda

Ho un motore delle regole, che supporta due modalità di operazioni:

  1. Compilazione in un programma C# e collegata al motore
  2. Analizzare un'istruzione basata su stack inversa e interpretato

Le regole sono semplici espressioni aritmetiche con chiamate di funzione (max, min, sin, cos ecc.)

Avrei ipotizzato che la versione compilata (cioè n. 1) fosse tanto Più veloce della versione interpretata (cioè n. 2) - in effetti, questo è il motivo principale per avere una modalità compilata in primo luogo. Tuttavia, i miei test di velocità hanno mostrato diversamente.

Versione compilata

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

Versione interpretata

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

Qui, "espressione" fa parte di una libreria di terze parti che analizza una semplice stringa in un semplice insieme di istruzioni basate su stack inversa inversa, che possono quindi essere interpretate. è non L'oggetto di espressione in LINQ-solo per chiarimenti.

Nota: non preoccuparti della concorrenza poiché nel codice reale, ordino le regole per "livelli" e calcola i livelli in sequenza, che ogni livello solo a seconda dei valori calcolati nei livelli precedenti. Entrambe le modalità hanno la struttura identica degli stessi livelli.

I risultati

Incredibilmente, la versione interpretata funziona TANTO Più veloce della versione compilata, in media un fattore 4x! In altre parole, la versione compilata ha impiegato 0,3 secondi per eseguire circa 1.200 regole, mentre la versione interpretata ha richiesto in media 0,08-0,1 secondi.

Il mio computer è un core2 così dual-core.

Sto usando .NET 4.0, Visual Studio 10.

Le prestazioni sono simili nelle build di debug o di rilascio.

La mia domanda

Cosa può causare il significativo rallentamento della modalità compilata?

Nota: ho pubblicato una possibile risposta

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top