On Thu, Oct 29, 2015 at 11:07 AM, Ben N <lazydo...@mac.com> wrote: > Hi > > I am just starting out with V8 and I'm slowly finding my way round it but I > have run into a problem. I'm sorry if this is a common question or if the > answer is obvious, but I have spent some time trying to Google it and I > haven't found a satisfactory explanation. > > The problem I have concerns the speed of calling a JavaScript function from > C++ which is very very slow. Compared to calling the same function from > JavaScript I"m finding it roughly 400 times slower. I've created a simple > function which highlights this speed difference and the code is below. > > Any advice on how fix this speed issue would be very much appreciated. I'm > developing on a Mac and Xcode by the way. > > thank you and apologies if I'm asking or doing anything dumb! > > b e n > > > This is what I have on the JavaScript side: > > var raycast_count ; > var raytracer = new kraytracer() ; > > raytracer.oncastray = function( x, y ) > { > ++ raycast_count ; > return true ; > } > > // this loop takes about 0.03 seconds to run > raycast_count = 0 ; > for ( var j = 0 ; j < 1980 ; ++j ) > for ( var i = 0 ; i < 1440 ; ++ i ) > raytracer.oncastray( i, j ) ; > > > // raytracer.begin() is C++ function that performs the same loop above. > // It takes 13 seconds though! > raycast_count = 0 ; > raytracer.begin() ; > > > > and on the C++ side I have a callback for raytracer.begin() which looks > roughly like this, > > void v8raytracer::begin( const FunctionCallbackInfo<Value> & info ) > { > ... > ... > > Local<Value> oncastray = info.This()->Get( String::NewFromUtf8( isolate, > "oncastray" ) ) ; > Handle<Value> parameters[ 2 ] ; > Local<Value> rcv = info.This() ; > > if ( oncastray->IsFunction() ) > { > Local<Function> oncastray_fn = Handle<Function>::Cast( oncastray ) ; > > for ( int j = 0 ; j < 1980 ; ++j ) > for ( int i = 0 ; i < 1440 ; ++i ) > { > parameters[ 0 ] = Integer::New( isolate, x ) ; > parameters[ 1 ] = Integer::New( isolate, y ) ; > > oncastray_fn->Call( rcv, 2, parameters ) ; > } > } > ... > ... > }
The short answer is to keep the number of C++ -> JS transitions to a minimum. If you look at the call stack in a debugger, you'll see why it's so much slower: V8 has to insert a couple of adapter frames that convert between the JS and C++ calling conventions. (Also, it can't inline the function body like it does for hot JS functions.) In most cases, the easiest solution is to batch arguments: instead of calling a native function ten times with one argument, call it one time with ten arguments. Look into using typed arrays for passing data, they're cheaper to inspect in C++ land than regular JS arrays; v8::Array::Get() is quite slow. -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.