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.

Reply via email to