As the title says, I am looking for the fastest way to wrap a native C++ object into a v8::Object. A sample of the code I currently have looks like:
Nan::Persistent<v8::Function> Vector3::constructor;
void Vector3::Initialise() // Static, Called once.
{
v8::Local<v8::FunctionTemplate> objectTemplate = Nan::New<v8::FunctionTemplate>();
objectTemplate->SetClassName(Nan::New("Vector3").ToLocalChecked());
objectTemplate->InstanceTemplate()->SetInternalFieldCount(1);
constructor.Reset(objectTemplate->GetFunction());
}
v8::Local<v8::Object> Vector3::WrapObject(double* components) // Static
{
v8::Local<v8::Function> constructorFunction = Nan::New(Vector3::constructor);
v8::Local<v8::Object> localObject = Nan::NewInstance(constructorFunction).ToLocalChecked();
Nan::Set(localObject, Nan::New("X").ToLocalChecked(), Nan::New<v8::Number>(components[0]));
Nan::Set(localObject, Nan::New("Y").ToLocalChecked(), Nan::New<v8::Number>(components[1]));
Nan::Set(localObject, Nan::New("Z").ToLocalChecked(), Nan::New<v8::Number>(components[2]));
return localObject;
}
The full code is a bit more complex as each vector is a property of some wrapped entity class.
From reading the many online tutorials and posts it seems like this is one of the most common ways to wrap an object, however, is there any faster way?
Profiling the code highlights Nan::Set as a major bottleneck. In particular, it seems Set internally calls two v8 methods:
v8::internal::Object::SetProperty
and
v8::internal::LookupIterator::PropertyOrElement
with each method taking up about 50% of the total Set function.
So my thoughts are:
Is there anyway to bypass the lookup function and call SetProperty directly?
Surely the lookup step is redundant here as I know ahead of time that I am setting a property and not an element.
Is there perhaps a way to define the properties on the object template in the Initialise method and then just set them using some integer index (while still retaining them as named properties and not elements) rather than the string name so the lookup is faster?
Is there any way to set multiple properties on an object at the same time?
Is there a better method entirely?
Related
I have a design annoyance with some existing code in JS. The code is working, so I have no desperate hurry to change it, but the duplication shown below does annoy me. What is the usual/recommended/official way of avoiding this situation?
The actual system is a large/complex financial system, so I have simplified it to the most basic example which demonstrates the problem:
var colours={
red:{id:"red", vals:[1,0,0]},
green:{id:"green", vals:[0,1,0]},
grey:{id:"grey", vals:[0.5,0.5,0.5]}
// ...etc
};
// id needs to be known internally within the object - thus it is defined as a property.
// e.g:
colour.prototype.identify(console.log(this.id));
// id also needs to be used externally to find an object quickly.
// e.g:
function getcolour(s){return colours[s];}
// Although this works. It does mean duplicating data, with the theoretical possibility of a mismatch:
var colours={//...
blue:{id:"green", // oh dear...
How would this normally be handled by the experts?
This question is somewhat subjective.
When creating my applications I typically try do do the following:
never define same data in multiple places. source should always be unambiguous
if I need to create any indices for faster/easier access, I use utility methods to do it. Those methods should be properly unit-tested, so that I would have little doubts on them doing the wrong thing
use third party libraries as much as possible (such as already suggested lodash or underscore) to minimize the amount of code to be written/maintained.
If your algorithms and utilities are properly unit-tested you should not worry (too much) about getting the data into inconsistent state. However, if those are critically important systems/interfaces, you may add some validation on output. And it is generally a good practice to have data validation and marshaling on input.
Explanation on the utility methods:
if you have data array, say
var data = [{"id":"i_1", ...}, {"id":"i_2", ...},{"id":"i_3",....}];
Then and you have to create an index out of that or create more data sets based on the original array, then you create yourself a library of utility methods that do the modification on the array, create derivative data sets, or iterate on the array and create a resulting item on the fly. For example:
var createIndex = function( arr ){
// do something that converts the data array with expected structure to object
// {
// i_1: {"id":"i_1", ...},
// i_2: {"id":"i_2", ...},
// i_3: {"id":"i_3", ...}
return newObj;
}
This method will create a hash-map to access your data, which is faster then to iterate over the original array all the time. But now, this method you can easily unit-test and be sure that when you use it on the source data to get your intended dataset, there will be no inconsistency.
I wouldn't change the colours[key] direct access with other method to avoid duplication.
Any other attempt will lead to processing and you have mentioned that you have a large amount of data.
I assume that the duplication is over the incoming data that is a waste.
An example of processing over the network data consuming could be, going over the map object and set the id dynamically according to the key. (processing vs traffic)
colours[key].id = key
You can filter your object converting it to an array of objects and then filtering unique values. Converting it to an array would allow you to perform a lot of operations quicker and easier.
So you can map your object to an array:
var coloursArray = myObj.map(function(value, index) {
return [value];
});
Remove duplicates:
function removeDuplicates() {
return coloursArray.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[id]).indexOf(obj[id]) === pos;
});
}
You can remove duplicates from an array using for example underscore.js through the .uniq method:
var uniqueColoursArray = _.uniq(coloursArray , function(c){ return c.id; });
Moreover, this function is pretty useless because you can access your element directly:
function getcolour(s){return colours[s];}
Calling colours[s] it is also shorter than getcolour(s). Your function would make sense if you pass also the array because it is not accessible in some other scope.
Then I can't understand why you do pass a console.log as parameter here:
colour.prototype.identify(console.log(this.id));
maybe you would like to pass just the this.id
I'm hoping to take advantage of underscore to avoid writing for loops throughout my code base. I'm using map in place of a for loop like so:
body.tags = _.map(body.tags, function(tag) {
return {
id: tag.id,
userId: tag.userId,
createDate: tag.createDate,
tag: tag.tag.toLowerCase(),
};
});
My question is, is there a way to do this without specifying the properties that won't be changing (everything but tag)? It seems like overkill to specify fields like id: tag.id.
You don't even need underscore for this:
body.tags.forEach(function(t) { t.tag = t.tag.toLowerCase();});
map (whether native, underscore or others) is used to transform whole values, it's not a typical use case to do what you tried to do with it. Also, using a simple for might perform better since you don't need function calls here, but that depends on runtime optimizations.
By the way, if you replace the mapping function with the function from this answer and not set the return value back to body.tags, you'll also get your desired result.
You could try the following code to change a single property in a collection using underscore.
_.map(body.tags, function(tag) {
tag.tag = tag.tag.toLowerCase();
return tag;
});
There is one benefit in using lodash's map method (similar to underscore library) over native forEach and its performance. Based on why lodash is faster than native forEach post, maybe it's justifiable to use lodash in favour of both underscore and native forEach to loop. However I would agree with the user who commented below "Choose the approach that is most writable, readable, and maintainable".
Given two Javascript objects (A and B), is there a way to generate the JSON patch, so that when that patch is applied to A it would change the object's properties to that of object B?
For example, given hypothetical JSONPatch function (perhaps being a function of similar name to one of those linked below), what is desired is the generate_patch function.
patch = generate_patch(A, B)
JSONPatch.apply(patch, A) # modifies A so that it has the same properties as B.
In this question A and B are Javascript objects. A patch created by RFC6902 is JSON that would indicate an array of operations which when applied to A that object would become B. The generate_patch function need not return JSON though, rather for efficiency could return a Javascript object that becomes the RFC6902 JSON-patch document when JSON.stringify is called on it.
The projects I have found on the topic are:
https://github.com/bruth/jsonpatch-js - only patches (does not generate a patch)
http://jsonpatchjs.com/ - same
https://github.com/Starcounter-Jack/Fast-JSON-Patch - observes an object, does not take two different objects
Turning my comment into an answer...
This code https://www.npmjs.org/package/rfc6902 seems to be a full javascript implementation of both patch and diff for the stated RFC.
I haven't used it myself, but the documentation makes it look like what you asked for.
Since version 0.3.9, https://github.com/Starcounter-Jack/Fast-JSON-Patch has a compare method which returns a difference between 2 objects. If I understand correctly, that may be what you were looking for
I have also written a library to generate patches: https://github.com/gregsexton/json-patch-gen
I found out about 'rfc6902' after having written and used json-patch-gen. I'm not sure how they compare: it may be worth trying out both to see if one fits your needs better.
EDIT
Did a JSPerf. Ran it against Chrome as Chrome uses v8.
http://jsperf.com/passing-large-objects
It looks like passing a large object doesn't matter; the difference is negligible. However, lookup on an object at some point gets a lot slower.
INTRODUCTION:
I’m writing a 2D JavaScript game engine while following component based and data oriented (via typed arrays) design principles. It’s designed for use by a simulation based multiplayer netcode.
My performance concerns are for the master simulation that will be running on the server; I believe that client browsers will be more than fast enough. As of now, the server is NodeJS, so it would involve the V8 interpreter. However, I’m not ruling out a switch to other technologies like Vert.x, which I believe uses the Rhino interpreter.
THE QUESTION:
When does JavaScript access objects in memory?
More specifically, let’s say I have an object like so.
var data = {
a1 : new Float64Array(123456),
a2 : new Float64Array(123456),
…
a9001: new Float64Array(123456)
};
And now let’s say I pass it to this function like so.
var update = function(obj) {
for(var property in obj) {
if(obj.hasOwnProperty(property)) {
obj[property][0]++;
}
}
};
update(data);
At what point are the Float64 arrays accessed? Does it access it the moment I pass data into update, attempting to load all 9001 arrays into the memory cache and page faulting like crazy? Does it wait to load the arrays until the hasOwnProperty? Or obj[property]? Or obj[property][0]?
WHY I ASK:
I’m trying to follow the data oriented design principles of keeping stuff in contiguous blocks of memory. Depending on how JavaScript works with memory, I will have to change the interface and structure of the engine.
For example, if all the arrays in data are accessed the moment I pass it into update, then I have to make special data objects with as few arrays as possible to reduce page faulting. If however the arrays are only accessed at say obj[property], then I can pass a large data object with more arrays without any performance penalties, which simplifies a lot of things.
A big reason why I’m not sure of the answer is because JavaScript objects aren’t objects like in other languages. From some random reading here or there, I’ve heard stuff like JavaScript objects have their own internal class. I’ve also heard of things like JavaScript objects being hash tables so you incur a lookup time with every property that you access.
Then I’ve heard that the interpreters treat objects differently based on how large the object is; smaller ones are treated one way and larger ones another. So jsperf stuff may not be an accurate measure.
FURTHER:
Taking the example further, there’s the question of how JavaScript handles nested objects. For example:
var properties = {
a1 : {
a1 : {
…
a1 : {
}
}
},
a2 : {
a2 : {
…
a2 : {
}
}
},
…
a9001 : {
a9001 : {
…
a9001 : {
}
}
}
};
var doSomething = function() {
};
doSomething(properties);
If passing in properties to doSomething causes every sub object and their sub objects to get accessed, then that’s a performance hit. If however it just passes a reference to the properties object and only accesses the sub objects when the code calls them, then it’s not bad at all.
If I had access to Vectors, I’d make an entity system framework in a heartbeat and this wouldn’t really be a problem. If I had access to pointers, which I believe only accesses the object when the code converts the pointer, then I could try other things. But only having typed arrays at my disposal limits my options, so I end up agonizing over questions like this.
Thanks for the any insight you can provide. I really appreciate it.
I'm starting to make use of virtual getter methods in Mongoose in a real-world application and am wondering if there is a performance impact to using them that would be good to know about up-front.
For example:
var User = new Schema({
name: {
first: String,
last: String
}
});
User.virtual('name.full').get(function () {
return this.name.first + ' ' + this.name.last;
});
Basically, I don't understand yet how the getters are generated into the Objects Mongoose uses, and whether the values are populated on object initialisation or on demand.
__defineGetter__ can be used to map a property to a method in Javascript but this does not appear to be used by Mongoose for virtual getters (based on a quick search of the code).
An alternative would be to populate each virtual path on initialisation, which would mean that for 100 users in the example above, the method to join the first and last names is called 100 times.
(I'm using a simplified example, the getters can be much more complex)
Inspecting the raw objects themselves (e.g. using console.dir) is a bit misleading because internal methods are used by Mongoose to handle translating objects to 'plain' objects or to JSON, which by default don't include the getters.
If anyone can shed light how this works, and whether lots of getters may become an issue at scale, I'd appreciate it.
They're probably done using the standard way:
Object.defineProperty(someInstance, propertyName, {get: yourGetter});
... meaning "not on initialization". Reading the virtual properties on initialization would defeat the point of virtual properties, I'd think.