On 18 October 2015 at 03:51, Jakob Kummerow <jkumme...@chromium.org> wrote:
> On Sat, Oct 17, 2015 at 12:20 AM, Dmitry Orlov <alepho...@gmail.com> > wrote: > >> Thanks Jacob! >> >> On 16 October 2015 at 13:56, Jakob Kummerow <jkumme...@chromium.org> >> wrote: >> >>> It's not about what the "internal array representation" is, it's about >>> how the array is accessed. V8 employs all sorts of smarts to make >>> JavaScript execution very fast, because that's its job. Accessing things >>> via the C++ API ("array->Set(...)" in your example) isn't anywhere near as >>> optimized. The difference is most pronounced for tight hot loops, it will >>> be much smaller (to the point of being negligible) for code that runs only >>> once. >>> >> Is there any way to bulk-allocate a v8::Array in a cheap way, for >> example, from a C-array of v8::Handle<v8::Value>s? >> > > The fastest way to exchange large amounts of data between C++ and JS is > probably an externalized > <https://chromium.googlesource.com/v8/v8/+/master/include/v8.h#3472> > ArrayBuffer, > which allows access to its raw backing store on the C++ side, and a > TypedArray on top of it on the JS side. > Yes, that works very fast too! However, in the real code, I have to pass large arrays of v8::Objects, not integers. It is possible to create an ArrayBuffer-backed array of object handles? void allocate_and_process_integer_array_buffer(benchmark::State& state) { v8::TryCatch try_catch(isolate); v8::HandleScope scope(isolate); v8::Local<v8::Script> script = v8::Script::Compile(v8::String::NewFromUtf8(isolate, "function array_sum(x) {" " var ret = 0;" " for (var i = 0; i < x.length; ++i) {" " ret += x[i];" " }" " return ret;" "}")); script->Run(); assert(!try_catch.HasCaught()); v8::Local<v8::Function> run = v8::Local<v8::Function>::Cast( context.Get(isolate)->Global()->Get(v8::String::NewFromUtf8(isolate, "array_sum"))); assert(!run.IsEmpty()); while (state.KeepRunning()) { const int n = state.range_x(); std::unique_ptr<int32_t[]> buf = make_unique<int32_t[]>(n); for (int i = 0; i < n; ++i) { buf[i] = i; } v8::Local<v8::ArrayBuffer> array_buffer = v8::ArrayBuffer::New(isolate, buf.get(), n * sizeof(buf[0])); v8::Local<v8::Int32Array> int_array = v8::Int32Array::New(array_buffer, 0, n); v8::Local<v8::Value> arg = v8::Local<v8::Value>::Cast(int_array); v8::Local<v8::Value> ret = run->Call(context.Get(isolate)->Global(), 1, &arg); assert(!try_catch.HasCaught()); assert(ret->IsNumber()); assert(v8::Local<v8::Integer>::Cast(ret)->Value() == n * (n - 1) / 2); } } BENCHMARK(allocate_and_process_integer_array_buffer)->Arg(1)->Arg(10)->Arg(100)->Arg(1000)->Arg(10000); allocate_and_process_integer_array_buffer/1 1535 1549 947585 allocate_and_process_integer_array_buffer/10 1559 1558 450880 allocate_and_process_integer_array_buffer/100 1986 1985 417042 allocate_and_process_integer_array_buffer/1000 3832 3830 158648 allocate_and_process_integer_array_buffer/9.76562k 23289 23273 32677 Dmitry. > > >> That said, if "Build Type: DEBUG" in your output means what I think it >>> means, then any performance measurement results are pretty much >>> meaningless. Try again in Release mode. >>> >> This message is reported because the Google benchmark library was build >> without NDEBUG directive: >> >> https://github.com/google/benchmark/blob/cf40a0f1172afc061e910eb5590f71e6ffdece66/src/console_reporter.cc#L43 >> Apparently, that is the way its Makefile is written. >> >> My code is compiled wtih -O3: >> CXXFLAGS=-Wall -Werror -g -O3 -march=corei7 -mtune=corei7-avx >> -std=gnu++0x -pthread >> >> Is it possible that I inadvertently built V8 in debug mode? This is how I >> install it: >> $ export PATH=$PATH:/path/to/depot_tools >> $ fetch v8 >> $ cd v8 >> $ git fetch >> $ git checkout 4.2.77.21 >> > > You should update, 4.2 is outdated and unmaintained. branch-heads/4.6 is > a good choice right now (tip of the branch that's used in Chrome's Stable > channel). > > >> $ gclient sync >> $ make clean >> $ make -j8 native >> > > OK, "make native" builds V8 in Release mode. > > >> >>> On Fri, Oct 16, 2015 at 8:57 PM, Dmitry Orlov <alepho...@gmail.com> >>> wrote: >>> >>>> Hello everyone, >>>> >>>> I've noticed peculiar performance characteristics of V8 objects when >>>> benchmarking my V8-embedding application. In particular, v8::Array is >>>> incredibly expensive - each Set(index, value) operation on an array >>>> consistently takes 100ns on a 3.4Ghz Xeon, instead of single digit >>>> nanoseconds one would expect from a C-array based implementation. >>>> In contrast, javascript code using arrays runs blaze-fast, taking >>>> around 2ns for each assignment. >>>> >>>> I've benchmarked these code fragments separately, implementation is >>>> below: >>>> >>>> void allocate_v8_integer_array(benchmark::State& state) { >>>> v8::HandleScope scope(isolate); >>>> v8::Local<v8::Value> int_value = v8::Integer::New(isolate, 100); >>>> while (state.KeepRunning()) { >>>> const int n = state.range_x(); >>>> v8::Local<v8::Array> array = v8::Array::New(isolate, >>>> state.range_x()); >>>> for (int i = 0; i < n; ++i) { >>>> array->Set(i, int_value); >>>> } >>>> } >>>> } >>>> >>>> void allocate_v8_integer_array_in_javascript(benchmark::State& state) { >>>> v8::TryCatch try_catch(isolate); >>>> v8::HandleScope scope(isolate); >>>> v8::Local<v8::Script> script = >>>> v8::Script::Compile(v8::String::NewFromUtf8(isolate, >>>> "function run(n) {" >>>> " var x = Array(n);" >>>> " for (var i = 0; i < n; i++) {" >>>> " x[i] = i;" >>>> " }" >>>> "}")); >>>> script->Run(); >>>> assert(!try_catch.HasCaught()); >>>> v8::Local<v8::Function> run = v8::Local<v8::Function>::Cast( >>>> >>>> context.Get(isolate)->Global()->Get(v8::String::NewFromUtf8(isolate, >>>> "run"))); >>>> v8::Local<v8::Value> arg = v8::Integer::New(isolate, >>>> state.range_x()); >>>> while (state.KeepRunning()) { >>>> run->Call(context.Get(isolate)->Global(), 1, &arg); >>>> assert(!try_catch.HasCaught()); >>>> } >>>> } >>>> >>>> Benchmark results: >>>> Run on (8 X 3399.98 MHz CPU s >>>> 2015-10-16 18:47:44 >>>> Build Type: DEBUG >>>> Benchmark Time(ns) CPU(ns) >>>> Iterations >>>> >>>> --------------------------------------------------------------------------------- >>>> allocate_v8_integer_array/1 190 190 >>>> 3688287 >>>> allocate_v8_integer_array/10 1061 1061 >>>> 659836 >>>> allocate_v8_integer_array/100 9936 9930 >>>> 70495 >>>> allocate_v8_integer_array/1000 96517 96458 >>>> 7259 >>>> allocate_v8_integer_array/9.76562k 967739 967146 >>>> 724 >>>> allocate_v8_integer_array_in_javascript/10 487 486 >>>> 3104447 >>>> allocate_v8_integer_array_in_javascript/100 1075 1074 >>>> 1000000 >>>> allocate_v8_integer_array_in_javascript/1000 3576 3573 >>>> 264306 >>>> allocate_v8_integer_array_in_javascript/9.76562k 22218 22204 >>>> 33641 >>>> >>>> Note how allocate_v8_integer_array asymptotes at 100ns per array >>>> assignment, where allocate_v8_integer_array_in_javascript asymptotes at 2ns >>>> per assignment. >>>> I would expect v8::Array to be the internal array representation for >>>> the javascript too. Is that not the case? Why the performance difference is >>>> so high? >>>> >>>> Thank you very much! >>>> Dmitry. >>>> >>>> -- >>>> -- >>>> 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. >>>> >>> >>> -- >>> -- >>> v8-users mailing list >>> v8-users@googlegroups.com >>> http://groups.google.com/group/v8-users >>> --- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "v8-users" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/v8-users/_fuFjcsktzc/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> v8-users+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- >> -- >> 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. >> > > -- > -- > v8-users mailing list > v8-users@googlegroups.com > http://groups.google.com/group/v8-users > --- > You received this message because you are subscribed to a topic in the > Google Groups "v8-users" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/v8-users/_fuFjcsktzc/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > v8-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- 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.