I am trying to run some code across multiple CPUs. Each cpu is given some tasks and then they return the result to the main thread which aggregates everything together.
What I don't understand is that whenever I send a message containing a Date Object, that Date Object is converted to a string. It seems ridiculous to have to parse these to dates both in the worker threads and in the main thread. I am working with a lot of dates, so this will have a huge performance hit.
Is there anything I can do to get around this? I am using node version v10.13.0.
const cluster = require('cluster');
if (cluster.isMaster) {
// init cluster
require('os').cpus().forEach(() => {
cluster.fork();
});
// add eventlisteners
Object.values(cluster.workers).forEach(worker => {
worker.on('message', message => {
console.log(typeof message); // string
});
});
} else {
process.send(new Date());
}
According to the 'message'
event's documentation:
The message goes through serialization and parsing.
The serialization of a Date
object is a string:
// serialize and rebuilds an object: { test: "2019-03-05T16:20:17.863Z" }
JSON.parse(JSON.stringify({test: new Date()}));
So, no, there's no workaround: each process (workers and master alike) have its own environment (i.e. its own space to store objects), so you can't share references across different environments. To illustrate:
const input = {some: 'thing'};
const output = JSON.parse(JSON.stringify(input));
console.log('are input and output the same object?', input === output); // false
If you're concerned about performance on this, maybe rethink your architecture so that workers don't need to send that many dates over the channel.
As a side note, you may have a boost in performance by using Date
's internal timestamp instead of the default time string:
const t0 = new Date();
for (let i = 0; i < 1000000; i++) {
const tmp = new Date();
// this took ~6.9s on JSFiddle
new Date(JSON.parse(JSON.stringify(tmp)));
// this took ~2.8s on JSFiddle
new Date(JSON.parse(JSON.stringify(+tmp)));
}
const t1 = new Date();
console.log('time spent', t1 - t0);