简体   繁体   中英

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));

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.

In the first example functions are getting created lazily only when their parent function is called, but in the second example all members are initialized as part of the object literal.

If you are trying to reduce your memory footprint , you should make use of the prototype chain which will allow you to share functions between multiple instances.

Basically, rather than doing:

function test() {
    var testvar = {
        someFn: function () {}
    };
}

You can do:

var base = {
    someFn: function () {}
};

function test() {
    var testvar = Object.create(base);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM