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 <
[email protected]> 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
> [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/d/optout.
>
--
--
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/d/optout.