When executing Chai Callback, RaiseException performance issue


#1

I’ve come across ChaiScript and was interested in trying it out as a way to script certain elements in my current project.

I’m currently using ChaiScript 5.5.1 on VC++ 2013

My first test was writing a callback, something like
fun(object) { return object.state == true; }

That is then evaled and stored in a std::function<bool(obj)>, and called from my c++ code, it seems to work; however I call this 900 times at the moment when switching between two states to update the display, when I do this the program basically freezes for 3 seconds in debug, ( 1 second in release )

I profiled the execution, and it seems that ~90% of the cpu time is spent in the windows method “RaiseException” called as an exception is thrown here:

Any idea if this is something that can be improved, either by changing how i’m using the chaiscript, or by improvements to chaiscript?


#2

If it’s any consolation, I can assure you it’s only slow because you’re running it in the debugger. A debug build run outside of the debugger, or a release build will be much faster.

It is not ideal that we use an exception to handle return it’s something my co-creator wants to eliminate, but I haven’t had time to spend on it.

All of that’s a long way of saying “Yes, I can offer you a simple work-around”

The return value of a statement in ChaiScript is the value of the last statement executed, so:

fun(object) { object.state == true; }

Will get you the exact same result while reducing the number of exceptions thrown and in general being faster, since the return doesn’t have to be processed.

A very simple optimization I’ll need to implement at some point would be simply removing the return if it’s the last statement in the function.

Hopefully that helps.


#3

Thanks for the feedback,

Removing return did have significant improvements while running the debugger, and minor improvements without.

I’ll leave the numbers I calculated here so you see the data.

ChaiScript - C++ Method Call, with single comparison, With return.
Debug Build; No Debugger: 186.88ms
Debug Build; With Debugger: 714.60ms
Release Build; No Debugger: 19.30ms
Release Build; With Debugger: 435.98ms

ChaiScript - C++ Method Call, with single comparison, No return:
Debug Build; No Debugger: 171.70ms
Debug Build; With Debugger: 245.71ms
Release Build; No Debugger: 13.40ms
Release Build; With Debugger: 23.15ms

C++ - C++ Method Call, with single comparison:
Debug Build; With Debugger: 1.48ms
Release Build; No Debugger: 0.08ms

All numbers are the average of several tests.


#4

That’s 900 callbacks in 13.4ms, best case? If that’s correct that’s ~15us / chaiscript function call?


#5

Yes, that is correct.


#6

I recently compared ChaiScript to a similar process of calling ruby->c++ (using SWIG to generate the interface) and saw a near identical performance between ChaiScript and Ruby for C++ method calls.

I find that quite acceptable, knowing that ChaiScript still has plenty of room to grow for performance, compared to the more mature Ruby.

Your numbers fall in line with what I would have expected.


#7

Oh, also, last I checked if you enable Whole Program Optimization in MSVC, you can expect to see another 15% improvement when using ChaiScript.


#8

FYI, I’ve got work in progress that eliminates return statements where possible: https://github.com/ChaiScript/ChaiScript/commit/40e2bf4099a89dc104944c0f0b5e6b78b16d4368


#9

Automatic removal of return statements when they are the last statement of the function is now a normal part of chaiscript, for anyone looking for info on this.


#10

Oh, and also, MUCH internal exception handling has been eliminated.