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.

Reply via email to