There are a bunch of optimizations going into object literal handling, so the two versions are not at all equivalent: the JS version is expected to be much faster. To make them more comparable, you could model the same control flow in JS, roughly:
var input = { "_id": { "$oid": "5a00bad8f759511811e030ba" }, "attributes": ... }; function process(o) { var result = {}; for (var key of Object.keys(o)) { var value = o[key]; if (typeof value === "Number") { ... } else if ... { .... } else if (typeof value === "object") { result[key] = process(value); } return result; } var output; for (var i = 0; i < 26400; i++) { output = process(input); } I don't see anything obviously wrong with your code. However, if there are any assumptions you can make, maybe you can optimize it. For example: do all your objects have the same shape? If so, using a constructor function and just filling in the values should be faster than assembling them one property at a time. On Tue, Nov 14, 2017 at 11:46 AM Jean-Marc Le Roux < jeanmarc.ler...@gmail.com> wrote: > Hello, > > I'm trying to create NodeJS bindings for libbson. > One of the things I need is to be able to transform a bson_t document into > a v8::Object. > Loading, iterating on bson_t documents and matching them with > MongoDB-style queries it very fast: 50ms to load from my HDD, iterate and > filter 26000 bson_t documents. > On the same machine, converting the same BSON documents into v8::Object is > painfully slow. > So I suspect I missed something. > > Here is my code: > > Local<Value> > iterator_to_value(Isolate* isolate, const bson_iter_t* iter) > { > switch (bson_iter_type(iter)) > { > case BSON_TYPE_INT32: > return Number::New(isolate, bson_iter_int32(iter)); > break; > case BSON_TYPE_INT64: > return Number::New(isolate, bson_iter_int64(iter)); > break; > case BSON_TYPE_DOUBLE: > return Number::New(isolate, bson_iter_double(iter)); > break; > case BSON_TYPE_DOCUMENT: > { > bson_iter_t sub_iter; > bson_iter_recurse(iter, &sub_iter); > > Local<Object> obj = Object::New(isolate); > while (bson_iter_next(&sub_iter)) > { > const char* key = bson_iter_key(&sub_iter); > > obj->Set( > String::NewFromUtf8(isolate, key), > iterator_to_value(isolate, &sub_iter) > ); > } > > return obj; > } > break; > case BSON_TYPE_ARRAY: > { > bson_iter_t sub_iter; > uint32_t length; > const uint8_t* array_data; > > bson_iter_array(iter, &length, &array_data); > bson_iter_recurse(iter, &sub_iter); > > Local<Array> array = Array::New(isolate); > int i = 0; > > while (bson_iter_next(&sub_iter)) > { > array->Set(i++, iterator_to_value(isolate, &sub_iter)); > } > > return array; > } > break; > case BSON_TYPE_OID: > { > const bson_oid_t* oid = bson_iter_oid(iter); > char oid_buffer[25]; > > bson_oid_to_string(oid, oid_buffer); > > return String::NewFromOneByte(isolate, (uint8_t*)oid_buffer); > } > break; > case BSON_TYPE_UTF8: > { > uint32_t length; > return String::NewFromUtf8(isolate, bson_iter_utf8(iter, > &length)); > } > break; > } > > return Null(isolate); > } > > Local<Value> > fill_object(Isolate* isolate, Local<Object>& obj, const bson_t* document) > { > bson_iter_t iter; > if (bson_iter_init(&iter, document)) > { > while (bson_iter_next(&iter)) > { > const char* key = bson_iter_key(&iter); > > obj->Set( > String::NewFromUtf8(isolate, key), > iterator_to_value(isolate, &iter) > ); > } > } > > return obj; > } > > As you can see, it's very straight forward. > *Transforming 26400 bson_t into v_::Object takes 1.23s.* > > I tried doing what I believe to be the same code in pure JS with a > representative sample Object : > > var array = []; > for (var i = 0; i < 25000; ++i) > { > array.push({ > "_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 > ] > }); > } > > *This pure JS version only takes 0.14s.* > > Why is my C++ code 10x slower than the equivalent JS code? > I suspect it has something to do with memory management/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.