Re: [v8-users] BSON to v8::Object performance issue

2017-11-15 Thread J Decker
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 Roux  wrote:

> 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

2017-11-15 Thread Jean-Marc Le Roux
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

2017-11-15 Thread Jean-Marc Le Roux
>
> 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

2017-11-15 Thread Jean-Marc Le Roux
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.