Re: [v8-users] BSON to v8::Object performance issue
I assume you're storing references to the objects as Persistent? All you need to do then is call SetWeak() https://v8docs.nodesource.com/node-0.10/d2/d78/classv8_1_1_persistent.html void MakeWeak (void *parameters, WeakReferenceCallback callback) the callback is called when the object is GC'd. On Wed, Nov 15, 2017 at 8:37 AM, Jean-Marc Le Rouxwrote: > So I've found a solution to make things lazy: I set an accessor instead of > decoding/setting the actual value. > > void > getter(Local property, const PropertyCallbackInfo& info) > { > Isolate* isolate = info.GetIsolate(); > > const bson_t* document = reinterpret_cast ( > info.This() > ->Get(String::NewFromUtf8(isolate, "__bson_document_ptr")) > ->ToInt32()->Value() > ); > > char key[255]; > property->ToString(isolate)->WriteUtf8(key, 255); > > bson_iter_t iter; > bson_iter_init(, document); > // FIXME: index the property so we don't have to find it > bson_iter_find(, key); > > // FIXME: replace the accessor with the deserialized value > > info.GetReturnValue().Set(iterator_to_value(isolate, )); > } > > Local > fill_object(Isolate* isolate, Local& obj, const bson_t* document) > { > obj->Set( > String::NewFromUtf8(isolate, "__bson_document_ptr"), > Int32::New(isolate, reinterpret_cast(document)) > ); > > bson_iter_t iter; > if (bson_iter_init(, document)) > { > while (bson_iter_next()) > { > const char* key = bson_iter_key(); > > if (!obj->Has(String::NewFromUtf8(isolate, key))) > { > obj->SetAccessor( > isolate->GetCurrentContext(), > String::NewFromUtf8(isolate, key), > > ); > } > } > } > } > > The secret sauce is to : > >- keep the original data (the bson_t) allocated >- store the corresponding pointer in a v8::Object > > But now I have a memory leak because those pointers will never be freed. > How can I know when the Object will be disposed by the GC? > > Thanks, > > -- > -- > 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 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.
Re: [v8-users] BSON to v8::Object performance issue
So I've found a solution to make things lazy: I set an accessor instead of decoding/setting the actual value. void getter(Local property, const PropertyCallbackInfo& info) { Isolate* isolate = info.GetIsolate(); const bson_t* document = reinterpret_cast( info.This() ->Get(String::NewFromUtf8(isolate, "__bson_document_ptr")) ->ToInt32()->Value() ); char key[255]; property->ToString(isolate)->WriteUtf8(key, 255); bson_iter_t iter; bson_iter_init(, document); // FIXME: index the property so we don't have to find it bson_iter_find(, key); // FIXME: replace the accessor with the deserialized value info.GetReturnValue().Set(iterator_to_value(isolate, )); } Local fill_object(Isolate* isolate, Local& obj, const bson_t* document) { obj->Set( String::NewFromUtf8(isolate, "__bson_document_ptr"), Int32::New(isolate, reinterpret_cast(document)) ); bson_iter_t iter; if (bson_iter_init(, document)) { while (bson_iter_next()) { const char* key = bson_iter_key(); if (!obj->Has(String::NewFromUtf8(isolate, key))) { obj->SetAccessor( isolate->GetCurrentContext(), String::NewFromUtf8(isolate, key), ); } } } } The secret sauce is to : - keep the original data (the bson_t) allocated - store the corresponding pointer in a v8::Object But now I have a memory leak because those pointers will never be freed. How can I know when the Object will be disposed by the GC? Thanks, -- -- 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.
Re: [v8-users] BSON to v8::Object performance issue
> > Now it takes *30ms. That's still 5x faster* than the native code. 300ms. (not 30) On Wed, Nov 15, 2017 at 10:27 AM, Jean-Marc Le Roux < jeanmarc.ler...@aerys.in> wrote: > Thanks for the quick feedback! > > I rewrote the JS version to be closer to the native one: > > var array = []; > var input = { > "_id": { > "$oid": "5a00bad8f759511811e030ba" > }, > "attributes": [ > { > "key": "smartshape.scene.node.path|default", > "value": "/scene/Lot444.scene", > "type": "imported" > }, > { > "key": "max x", > "value": 196.5773162841797, > "type": "computed" > }, > { > "key": "max y", > "value": 18.55002021789551, > "type": "computed" > }, > { > "key": "max z", > "value": 22.87815856933594, > "type": "computed" > }, > { > "key": "min x", > "value": 149.9346771240234, > "type": "computed" > }, > { > "key": "min y", > "value": 18.54999732971191, > "type": "computed" > }, > { > "key": "min z", > "value": -23.35353088378906, > "type": "computed" > }, > { > "key": "box radius", > "value": 23.32131958007814, > "type": "computed" > }, > { > "key": "center x", > "value": 173.25599670410156, > "type": "computed" > }, > { > "key": "center y", > "value": 18.55000877380371, > "type": "computed" > }, > { > "key": "center z", > "value": -0.23768615722655895, > "type": "computed" > }, > { > "key": "width", > "value": 46.64263916015628, > "type": "computed" > }, > { > "key": "height", > "value": 2.2888183600855427e-05, > "type": "computed" > }, > { > "key": "depth", > "value": 46.231689453125, > "type": "computed" > }, > { > "key": "box volume", > "value": 0.04935534689932106, > "type": "computed" > }, > { > "key": "box surface", > "value": 4312.740269302394, > "type": "computed" > } > ], > "name": "default1161", > "uuid": "70bf7d72-1fa9-5c8f-21ff-03ef209d4404", > "surfaces": [ > "6f5201a2-31a7-14d0-6b2a-5130007d2a51" > ], > "aabb": [ > 196.5773162841797, > 18.55002021789551, > 22.87815856933594, > 149.9346771240234, > 18.54999732971191, > -23.35353088378906 > ], > "position": null, > "scale": null, > "rotation": null, > "parents": [ > "18497b66-3f32-6e98-1899-2998203e6397", > null > ], > "file": "5a00b9a4aa5d2517d32d03da", > "numChildren": 0, > "sceneTreeIndices": [ > 0 > ] > }; > > function process(value) { > if (typeof value === "number") { > return value; > } else if (typeof value === "string") { > return value; > } else if (Array.isArray(value)) { > var array = []; > > for (var item of value) { > array.push(process(item)); > } > > return array; > } else if (typeof value === "object") { > > if (!value) { > return value; > } > > var obj = {}; > for (var key of Object.keys(value)) { > obj[key] = process(value[key]); > } > > return obj; > } else { > return value; > } > > return value; > } > > for (var i = 0; i < 26000; ++i) { > var obj = process(input); > > array.push(obj); > } > > > > Now it takes *30ms. That's still 5x faster* than the native code. > > I'm suspecting my Local are copied/GCed multiple time to build the > final object. > Isn't that the case? > Is there a better way to do it? > > using a constructor function and just filling in the values should be >> faster than assembling them one property at a time. > > > The root object is expected to be the same 99% of the time. > Each of his field too. > So I could definitely have a map. > How can I implement such a constructor function in v8 ? > > Thanks ! > > -- > -- > 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/aVeevQcHJ2c/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. > -- *Jean-Marc Le Roux* Founder and CEO of Aerys (http://aerys.in) Blog: http://blogs.aerys.in/jeanmarc-leroux Phone: (+33)6 20 56 45 78 -- -- 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.
Re: [v8-users] BSON to v8::Object performance issue
Thanks for the quick feedback! I rewrote the JS version to be closer to the native one: var array = []; var input = { "_id": { "$oid": "5a00bad8f759511811e030ba" }, "attributes": [ { "key": "smartshape.scene.node.path|default", "value": "/scene/Lot444.scene", "type": "imported" }, { "key": "max x", "value": 196.5773162841797, "type": "computed" }, { "key": "max y", "value": 18.55002021789551, "type": "computed" }, { "key": "max z", "value": 22.87815856933594, "type": "computed" }, { "key": "min x", "value": 149.9346771240234, "type": "computed" }, { "key": "min y", "value": 18.54999732971191, "type": "computed" }, { "key": "min z", "value": -23.35353088378906, "type": "computed" }, { "key": "box radius", "value": 23.32131958007814, "type": "computed" }, { "key": "center x", "value": 173.25599670410156, "type": "computed" }, { "key": "center y", "value": 18.55000877380371, "type": "computed" }, { "key": "center z", "value": -0.23768615722655895, "type": "computed" }, { "key": "width", "value": 46.64263916015628, "type": "computed" }, { "key": "height", "value": 2.2888183600855427e-05, "type": "computed" }, { "key": "depth", "value": 46.231689453125, "type": "computed" }, { "key": "box volume", "value": 0.04935534689932106, "type": "computed" }, { "key": "box surface", "value": 4312.740269302394, "type": "computed" } ], "name": "default1161", "uuid": "70bf7d72-1fa9-5c8f-21ff-03ef209d4404", "surfaces": [ "6f5201a2-31a7-14d0-6b2a-5130007d2a51" ], "aabb": [ 196.5773162841797, 18.55002021789551, 22.87815856933594, 149.9346771240234, 18.54999732971191, -23.35353088378906 ], "position": null, "scale": null, "rotation": null, "parents": [ "18497b66-3f32-6e98-1899-2998203e6397", null ], "file": "5a00b9a4aa5d2517d32d03da", "numChildren": 0, "sceneTreeIndices": [ 0 ] }; function process(value) { if (typeof value === "number") { return value; } else if (typeof value === "string") { return value; } else if (Array.isArray(value)) { var array = []; for (var item of value) { array.push(process(item)); } return array; } else if (typeof value === "object") { if (!value) { return value; } var obj = {}; for (var key of Object.keys(value)) { obj[key] = process(value[key]); } return obj; } else { return value; } return value; } for (var i = 0; i < 26000; ++i) { var obj = process(input); array.push(obj); } Now it takes *30ms. That's still 5x faster* than the native code. I'm suspecting my Local are copied/GCed multiple time to build the final object. Isn't that the case? Is there a better way to do it? using a constructor function and just filling in the values should be > faster than assembling them one property at a time. The root object is expected to be the same 99% of the time. Each of his field too. So I could definitely have a map. How can I implement such a constructor function in v8 ? Thanks ! -- -- 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.