In which I accidentally discover a performance enhancement
I’m really not a fan of the massive switch statement at the heart of the execution loop, so I have decided to see if I can do something with virtual functions or closures on a WordList
. The execute
function would be reduced to running a particular function on the WordList
. Before doing that though, I had to get rid of the generic nature of the function. This I did simply by making the output
stream a property of the Forth machine and deleting the parameter.
Having effected that change, which was not that easy – you have to type erase the TextOutputStream
otherwise, once you’ve created a Forth machine, you are irrevocably committed to one particular type that conforms to TextOutputStream
– I ran a performance test to see how much I had lost. Typical performance before the above changes looks something like this.
Mean time = 0.9190
Mean mips = 5.891
Imagine my surprise when, after the changes, the stats looked like this:
Mean time = 0.2433
Mean mips = 22.25
This is a speed increase of nearly four times. My assumption is that the generic parameters for execute
and resume
added quite a lot of overhead. Anyway, I’ve since bumped the Fibonacci calculation I am using as a benchmark from 26 to 30 to keep the two figures I am graphing within a reasonable number of orders of magnitude. This has added another marginal speed bump but only because the overhead of the interpretation of 30 fibo .
is a smaller proportion of the total time.
I was working on my “direct execution” model in a separate branch, but because the speed increase is so dramatic, I’ve merged the changes back into master. The code is tagged blog-1352.