c# - Compiled expressions run much slower than interpreted versions -


i have rules engine, supports 2 modes of operations:

  1. compilation c# program , linked engine
  2. parsing reverse-polish stack-based instructions , interpreted

the rules simple arithmetical expressions function calls (max, min, sin, cos etc.)

i have assumed compiled version (i.e. #1) much faster interpreted version (i.e. #2) -- in fact, that's main reason having compiled mode in first place. however, speed tests showed otherwise.

compiled version

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 rules.asparallel().forall(r => r(...)); // end timer 

interpreted version

expression[] rules = ... // each rule parsed expression object, set of // reverse-polish stack-based instructions. // example, "x3=x12+x15/x20" parsed to: //     [ push(12), push(15), push(20), divide(), add() ] // start timer rules.asparallel().forall(r => r.evaluate(...)); // end timer 

here, "expression" part of third-party library parses simple string simple set of reverse-polish stack-based instructions, can interpreted. not expression-tree object in linq -- clarification.

note: don't worry concurrency since in real code, sort rules "layers" , calculate layers sequentially, each layer depending on values calculated in previous layers. both modes have exact same layers structure.

the results

shockingly, interpreted version runs much faster compiled version, average factor of 4x! in other words, compiled version took 0.3s run through around 1,200 rules, while interpreted version took on average 0.08-0.1s.

my computer so-so dual-core core2.

i using .net 4.0, visual studio 10.

performance similar in debug or release builds.

my question

what can causing significant slowdown in compiled mode?

note: have posted 1 possible answer

.net jit-compiled environment, more code jit-compile, slower is. can 1,200 methods jit-compiled @ run-time @ point of execution, vs. in interpreted mode interpreter jit-compiled, once. may seeing jit times in loops compiled mode.

experiment:

  1. run each mode 5 times (just complete jit compilation , fill caches)
  2. time 50 runs, take average

results:

  1. compiled mode: 1.6ms per run
  2. interpreted mode: 5.3ms per run

observations:

it appears large amount of time spent during first run of compiled mode.

the second run of compiled mode similar in speed interpreted mode.

the interpreted mode not speed significant number of runs.

thus suggesting point of view rule code jit-compiled during first run.


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -