Saturday, February 4, 2017

Node js C++ Addon Overload Resolution - v0.5.0

After being stuck with a few tests for node-alvision, I've decided to see why they take so much time.

From what I could gather while doing performance analysis, the major bottlenecks were the functions that determine the appropriate overload in general and the ones that do the actual type analysis and convertible checks.

Doing type analysis in v8 is not so straight forward as it seems, numbers are convertible to strings and back, almost anything can be converted to boolean and on top of that, checking if a certain object belongs to a C++ class also needs some work.

What the POC did is go over all the registered types and then determine which type the class belongs to but that can be shortened to checking only the names of the prototype chain, so if we have a type system of 230 types give or take, it will go over 3-5 the most after the change.

Now, if we have a function with 10 parameters and with 10 overloads, it would go over 100 type checks the most. so I've took out the arguments checks out of the overload matching function and created another object called function_arguments, which queried the argument type only once instead of multiple times and returned a cached result.

Another performance improvement is the array type checks, which went over the entire array and checked each element type, instead of it, I've decided to make it a little less reliable for the sake of performance, so now it will check 10 the most, so if we have a 1000 items in the array, it will skip every 100 items and check only their types.

So all of these are actually a sort of type system, which I refactored it into a new type_system class.

While it did boost the performance, I wasn't pleased with the boost, so instead of waiting about a minute for results, it would take only 20 seconds.

I went ahead and analyzed the bottlenecks further and found it that while the type checks themselves are no longer an issue, going over 10-20 overload for certain functions is still time consuming and after doing it once, if I know the argument types, there's no reason to do it again for the same function/classes.

This is where function_rank_cache class came into play, it caches the correct function given the same conditions apply, same class/function and argument types.

This improved the performance greatly and now I'm left with about 5 seconds of actual testing time for the said test.

All of these improvements were made in Debug, compiling it as Release improved things beyond my expectations for the moment.

In the end, what helped the most is doing only the work necessary :-)

No comments:

Post a Comment