optimization - Make interpreter execute faster -
i've created interprter simple language. ast based (to more exact, irregular heterogeneous ast) visitors executing , evaluating nodes. i've noticed extremely slow compared "real" interpreters. testing i've ran code:
i = 3 j = 3 has = false while < 10000 j = 3 has = false while j <= / 2 if % j == 0 has = true end j = j+2 end if has == false puts end = i+2 end
in both ruby , interpreter (just finding primes primitively). ruby finished under 0.63 second, , interpreter on 15 seconds.
i develop interpreter in c++ , in visual studio, i've used profiler see takes time: evaluation methods. 50% of execution time call abstract evaluation method, casts passed expression , calls proper eval method. this:
value * eval (exp * exp) { switch (exp->type) { case exp_addition: eval ((additionexp*) exp); break; ... } }
i put eval methods exp nodes themselves, want keep nodes clean (terence parr saied reusability in book).
also @ evaluation reconstruct value object, stores result of evaluated expression. value abstract, , has derived value classes different types (that's why work pointers, avoid object slicing @ returning). think reason of slowness.
how make interpreter optimized possible? should create bytecodes out of ast , interpret bytecodes instead? (as far know, faster)
here source if helps understanding problem: src
note: haven't done error handling yet, illegal statement or error freeze program. (also sorry stupid "error messages" :))
the syntax pretty simple, executed file in otz1core/testfiles/test.txt (which prime finder).
i appreciate can get, i'm beginner @ compilers , interpreters.
one possibility speed-up use function table instead of switch dynamic retyping. call typed-eval going through @ least one, , possibly several, levels of indirection. if distinguish typed functions instead by name , give them identical signatures, pointers various functions can packed array , indexed type member.
value (*evaltab[])(exp *) = { // order of functions must match exp_add, // order type values //... };
then whole switch becomes:
evaltab[exp->type](exp);
1 indirection, 1 function call. fast.
Comments
Post a Comment