Search code examples
javascriptnode.jsv8

Differences between functions and objects, and how it affects performance


Could anyone shred some light on why there seems to be such a great difference in memory footprint between the two examples shown below? I'm using node.js as environment.

They both produce the same result and mapping

var util = require('util');

var startMem = process.memoryUsage().heapUsed;

/*
var test = function() {

    var testvar = function() {
        this.innerTest1 = function() {
            this.someVal1 = "this is a test";
            this.someFunc1 = function() {
                return "this is another test";
            }
        }
        this.innerTest2 = function() {
            this.someVal2 = "this is a third test";
            this.someFunc2 = function() {
                return "this is a forth test";
            }
        }
    }
}
*/
//out:
//mem: 448088


var test = function() {
    var testvar = {
        innerTest1 : {
            someVal1 : "this is a test",
            someFunc1 : function() {
                return "this is another test"
            }
        },
        innerTest2 : {
            someVal2 : "this is a third test",
            someFunc2 : function() {
                return "this is a forth test"
            }
        }
    }
}

for (var i = 0; i < 50000; i++) {
    var testobj = new test();
}

//out:
//mem: 1060040


console.log("mem: " + (process.memoryUsage().heapUsed - startMem));

Solution

  • The two snippets of code have entirely different behavior.

    In the first example, the properties/functions are not set or created until the containing functions are invoked. However, the containing functions are never invoked.

    For instance, given:

       this.innerTest1 = function() {
            // the property is NOT SET until this function is run
            this.someVal1 = "this is a test";
            // this function is NOT CREATED until this function is run
            this.someFunc1 = function() {
                return "this is another test";
            }
        }
    

    Likewise, the same applies for assigning to innerTest1. Thus, the first example code is equivalent the following which is not very useful.

    var testvar = function() {}
    

    (The parsing can be considered a one-time cost.)

    In the later example, every property is assigned and every function is created as part of the object literal evaluation.