Description
What is the problem this feature will solve?
At the moment, there are a few ways to create objects using the napi C APIs.
napi_create_object
, and thennapi_set_named_property
for each property.napi_create_object
, and usenapi_define_properties
to set all properties at once (under the hood it still sets them one by one though).- use
napi_define_class
+napi_new_instance
, and then add properties using one of the above methods. You can define accessors on the prototype, or primitive values but instance properties must be set the same way as above.
In my use case I need to create a lot of small objects of the same shape. I've noticed in profiling that v8 functions under napi_set_named_property
are slow, specifically v8::internal::JSObject::MigrateToMap
. From my research in the v8 source code, this indicates that the object is transitioning from a fast struct/class-like object to a slower dictionary representation (I could be wrong here).
I think v8 exposes ObjectTemplate
and FunctionTemplate->InstanceTemplate
which are meant to help with this by defining the instance properties up front. This way, the object property slots can be allocated in the object itself rather than in a separate hash map. I found some useful info about v8 object representations here. I see that Node makes use of ObjectTemplate
for internal objects, and a previous issue nodejs/node-addon-api#1074 also found this to be the fastest way to create objects (though still not as fast as doing it in JS).
My problem is that napi does not expose a way to create an object together with its properties, or a way to define a template for class instance properties. This means, as far as I can tell, all objects constructed through napi will end up in the slow dictionary mode, leading to slower perf when both constructing and accessing properties.
What is the feature you are proposing to solve the problem?
It would be awesome if node exposed a new napi_create_object_with_properties
function, which would accept a list of property descriptors like napi_define_properties
and allocate an object and assign properties all at once. This could potentially allow using faster v8 methods to create the object and assign properties so that it doesn't go into hashmap mode when adding properties one by one.
Alternatively, a way to define an instance property template for classes would also work for me. For example, napi_property_attributes
could be extended with a napi_instance
attribute for defining properties on the instance template rather than the prototype template.
What alternatives have you considered?
I'm not a node or v8 internal expert, just noticed that setting properties on objects seemed slower than expected, so I could be totally wrong about everything above. Opening this issue to get a conversation started. Totally open to other suggestions!
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status