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.

Reply via email to