On Thu, Nov 14, 2013 at 2:28 PM, Dmitry Lomov <[email protected]> wrote:
> Thanks a lot for your yelling :)
>
> My general remark here is if you implement your own Buffer classes and not
> doing what the rest of the language does, in the long run you will not be
> able to benefit from all optimizations we will be doing to speed up
> ArrayBuffers and typed arrays.

I don't disagree with that point.  If we were just starting out, typed
arrays would be the obvious choice.  But there were no typed arrays in
the early days of node.js, they were still a glimmer in the eye of the
Khronos group.

So we have the Buffer class and a large body of code that's built
around it.  One in two modules on npm probably uses it in some way or
another.

> I know that our d8 implementation of ArrayBuffers and friends has been
> pretty terrible w.r.t. allocation speed, but it is already improving and
> will improve further.
>
>
> On Wed, Nov 13, 2013 at 12:08 AM, Trevor Norris <[email protected]>
> wrote:
>>
>>
>>
>> On Tuesday, November 12, 2013 12:08:28 AM UTC-8, Dmitry Lomov wrote:
>>>
>>> These implementations feature faster allocation, better garbage
>>> collection performance and a potential to become even faster in the future
>>> with deep compiler optimizations - they are the finest available.
>>
>>
>> Except they are at least twice as slow as our Node's internal Buffer
>> implementation for allocations over 1KB. I've been on the receiving end of
>> much debate about why Node doesn't transition to using ArrayBuffers and the
>> bottom line is always performance.
>
>
> Is it still true in the latest releases (3.20 and up)? I am curious as to
> what is the bottleneck here.
> I remember you pointing out (in a different bug) that allocating weak
> handles is costly - non-externalized ArrayBuffers do not require any weak
> handles anymore, and we can think of ways to avoid weak handle allocation
> for some externalized array buffers as well.
>
> Ben mentioned zero-initialization: in my tests, zero-initialization cost was
> actually pretty small (maybe within 5%). Of course, we will never be able to
> ship something exposing uninitialized external memory to Javascript.

In the v0.3.x days we had, for a short while, bzero-ing Buffers.  That
was a change that quickly got reverted when people started complaining
about ~30% performance drops.

That number makes sense in a way because a common use case for Buffers
is a) instantiate a buffer, then b) copy data into it.  Zeroing the
memory in step a) then simply wastes CPU cycles.

That said, I can think of one or two solutions to the zeroing overhead
issue, like mapping and pre-faulting memory in a separate thread.
That gives you zero-initialized memory without the main thread
incurring the performance penalty.

(Caveat emptor: this is me brainstorming while still nursing my first
coffee of the day, no doubt you can come up with a better solution.)

>> Other than the fact that instantiating an ArrayBuffer is slower, there's
>> the lost consideration of then needing to turn that into a Uint8Array before
>> it's usable.
>
>
> You can allocate Uint8Array directly (I know it allocates an ArrayBuffer
> under the hood now - getting rid of that for some/most cases is one of my
> optimization goals).
>
>>
>> What I feel you're considering a nuisance, being able to set external data
>> to any object, has been an excellent feature. With the release of Node v0.12
>> there's a new API that'll allow users to roll out their own Buffer-like
>> classes. Making it easy to extend a constructed instance with data and
>> easily exposing a set of methods to work with the data. I myself have been
>> using this as a simplified way to create mathematical API's around the
>> object's instance directly. Instead of needing to pass around an Type Array
>> View.
>>
>> We use it extensively as an extremely light weight way of sharing state
>> between C++ and JS. Currently it's ridiculously slow to read Object
>> properties from a JS Object in C++, so a technique has been used where a
>> struct is wrapped around a set of data in C++ and that same data is attached
>> to an Object in JS. This way they can communicate as quickly as possible.
>> This has allowed significant performance gains. When the Function is a
>> singleton it's also useful to attach the memory directly to the Function
>> instead of an Object somewhere close by.
>
>
> It feels like this scenario can be adequately captured by having an
> ArrayBuffer wrapping external data. It also aligns closely to the goals of
> typed objects proposal (formerly binary data:
> http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), and again
> that is probably what V8 will be optimizing for.
>
> Looking through Buffer API
> (http://nodejs.org/api/buffer.html#buffer_buffer), I think that everything
> there can be implemented by subclassing Uint8Array (admittedly, we do not
> support subclassing of builtin objects yet! :))

Right.  In a quick experiment I did a few days ago, I could only get
that to work by mucking around with this.__proto__ and delegating
properties with this.__defineGetter__.

> Anyway, given how deep this external data feature had taken deep roots in
> node.js code, I agree that completely deprecating this API is premature.
> Here are the steps I would still like to do though:
> - Does node.js use any ExternalArrayType besides kExternalUnsignedByteArray?
> I'd love to reduce at least this part of the zoo.

We do but only in code that hasn't made its way into a stable release
yet.  We could still roll that back.

> - I would dearly love to make sure node.js can switch to standard JS
> features instead of inventing your own. Can haz some benchmarks? :) I
> definitely do not want to force it down your throat though - I would like to
> get the perf to the point where the switch will be a perf win.
>
> Cheers,
> Dmitry

-- 
-- 
v8-users mailing list
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to