Inist-CNRS / node-xml-writer

Javascript implementation of the classic XMLWriter class
Other
61 stars 28 forks source link

XML Writer Performance Consideration #1

Open AlgoTrader opened 12 years ago

AlgoTrader commented 12 years ago

I like your xml-writer, in npm you can see another dependancy. I use your module to generate dozens of small XMLs in a second. I construct lots of XMLWriter objects.

Each time XML writer is created, constructor init all the methods. We can remove initing methods in constructor by using XmlWriter.prototype. Prototype is fully initialized in the first require, while constructor is called million times a day. I know it breaks the clouse, but I think it should not be a problem as you use this.something and this is properly inited in prototype methods

I propose changing this.startElement = function(name) { ...

with

XMLWriter.prototype.startElement = function(name) { ...

So instead of the single constructor function with all the job there we will have a lightweight constructor plus a prototype that is shared among millions of XMLWriter instances

AlgoTrader commented 12 years ago

The issue is discussed at StackOverflow: Advantages of using prototype, vs defining methods straight in the constructor? http://stackoverflow.com/questions/4508313/advantages-of-using-prototype-vs-defining-methods-straight-in-the-constructor

The fast quote: The advantage of the prototype approach is efficiency. There is one calc() function object shared between all Class objects (by which I mean objects created by calling the Class constructor). The other way (assigning methods within the constructor) creates a new function object for every Class object, using more memory and taking more processing time when calling the Class constructor.

touv commented 12 years ago

I can not remember why I used definning functions. For my others packages, I use prototype... I will refactor the code as soon as possible. But if you want, you can send me a pull request and I will publish a new version more quickly

AlgoTrader commented 12 years ago

I got a performance testing with your current module and slightly optimized module. I moved to the prototype the single method startDocument. The test code is there

var XmlWriter = require('xml-writer');

console.time('perftest');
for(var cnt=0; cnt<1000000; ++cnt) {
    var xw = new XmlWriter();
}
console.timeEnd('perftest');

Results are very surprising, I expected performance gain but not so big. Before:

zemlyanov@linux-sgvr:~/tmp> node test.js perftest: 6499ms

zemlyanov@linux-sgvr:~/tmp> node test.js perftest: 6385ms

After:

zemlyanov@linux-sgvr:~/tmp> node test.js perftest: 4159ms

zemlyanov@linux-sgvr:~/tmp> node test.js perftest: 4207ms

I got another test. First I made a bare constructor function without "child" methods inside. The 1,000,000 objects were created in 20ms. Then I added a single method this.method = function() ... and next run taken some 210ms to run.

Resume: performance gain of moving methods to prototype is very significant, it's worth job to do. I will make pull request. I will try to minimize code impact by using literal object style for defining prototype.