Some quick replies inline.
On Tue, Nov 19, 2013 at 1:10 AM, Trevor Norris <[email protected]>wrote: > > > On Thursday, November 14, 2013 5:28:58 AM UTC-8, Dmitry Lomov wrote: >> >> 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. >> > > I'm just curious. What was the change where you don't have to allocate > weak handles for ArrayBuffers? > Here is the change: https://code.google.com/p/v8/source/detail?r=15205 Instead of weak handles, I taught our GC to free array buffer backing store when array buffers die. > > >> 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! :)) >> > >> 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. >> - 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. >> > > Here's a table of benchmarks. The "Buffer 3.19" column is allocating a > Buffer object at v8 v3.19.x (before we upgraded). Then the "smalloc" column > is our internal allocator for Buffers. It's there twice to show that > between 3.19 and 3.22 something happened that caused the API to become > slower than it used to be for small allocations (maybe you know why this > happened?). The values are nanoseconds per operation. > > size Buffer 3.19 smalloc 3.19 smalloc 3.22 Uint8Array > Uint8Array slice > > ----------------------------------------------------------------------------------- > 1 byte: 165.2 293.0 401.4 193.9 113.2 > 16 bytes: 170.9 280.4 384.8 191.2 111.7 > 256 bytes: 210.9 312.7 434.6 250.9 117.0 > 1 KB: 332.3 453.4 547.2 747.8 222.4 > 16 KB: 531.5 454.2 581.8 1980.5 1883.9 > 256 KB: 1977.9 1937.1 2183.7 2054.2 1878.1 > 1 MB: 6626.9 6744.8 7562.2 7040.7 6797.0 > 16 MB: 95037.3 88270.4 104992.8 108304.6 109316.1 > > So here you can see that using a similar slicing technique, Uint8Array is > faster than our current implementation for small allocations. The > "Uint8Array slice" uses the same approach as Node's Buffers by creating an > 8KB pool and handing back chunks of that for allocations < 4KB. > > Though as you can see there's a block of sizes where it's strangely > slower. Here's a table with more information: > > size Uint8Array smalloc > ----------------------------- > 1 byte: 195.3 407.6 > 16 bytes: 208.5 380.8 > 256 bytes: 257.9 435.8 > 1 KB: 741.0 536.0 > 2 KB: 1116.8 557.2 > 4 KB: 1823.9 602.1 > 8 KB: 1828.9 567.3 > 16 KB: 1848.9 555.7 > 32 KB: 461.5 648.3 > 64 KB: 686.3 894.3 > 128 KB: 1085.0 1351.0 > 256 KB: 1858.9 2166.0 > 512 KB: 3792.9 3992.7 > 1 MB: 6664.3 6997.9 > > Off the top of my head, this smells like GC kicking in, although it does not explain why this is not reproducible with a native callback below. Can you share code for these benchmarks? > Time cost of instantiation is pretty much linear with smalloc, but not so > with Uint8Array. And there's a large block in there were Node spends a lot > of time instantiating new objects. Maybe you could also shed some light on > why this is happening. What's stranger still is that if I make a call to a > native module myself, say like this: > > void Allocate(const FunctionCallbackInfo<Value>& args) { > uint32_t size = args[0]->Uint32Value(); > args.GetReturnValue().Set(Uint8Array::New( > ArrayBuffer::New(size), 0, size)); > } > > instead of just calling new Uint8Array(size), the performance problem > demonstrated above doesn't occur. > > Anyways. I'd be sad to see the external array data API disappear. It's > been very helpful in creating APIs where you can attach data directly to a > constructed instance. This has been useful many things. One example is a > math library I'm working on where you can specify what type of data you > want to use (e.g. a kExternalDoubleArray), and it returns a new instance > where you can access the indexed data but also have many methods you can > run directly on the data. It's much faster to do even simple things in a > C++ module than in JS (e.g. take the sum of the array). Most of this thanks > to performance improvements you all have made to calling a native method > (thanks for that :). > > -- > -- > 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. > -- -- 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.
