javascriptnode.jsperformanceperformance-testing

Why so bad the performance of the NodeJS object creation if num of props greater than 8?


I would like to know that there are any limit in NodeJS when create an object which has more than 8 properties? I made a benchmark test and it seems if the object has more than 8 properties, the performance will be bad.

Test suite: https://github.com/icebob/js-perf-benchmark/blob/master/suites/properties.js (full copy at end of question)

The result:

Code:

bench.add("Create object with 8 prop", () => {
    let opts = {
        prop1: 5,
        prop2: "",
        prop3: false,
        prop4: 1,
        prop5: 0,
        prop6: null,
        prop7: "Hello",
        prop8: 12345
    };
    return opts;
});

bench.add("Create object with 9 prop", () => {
    let opts = {
        prop1: 5,
        prop2: "",
        prop3: false,
        prop4: 1,
        prop5: 0,
        prop6: null,
        prop7: "Hello",
        prop8: 12345,
        prop9: "asd"
    };
    return opts;
});

Environment:


Here's the content of the linked test suite above:

"use strict";

let Benchmarkify = require("benchmarkify");
let benchmark = new Benchmarkify("Object properties").printHeader();

let bench = benchmark.createSuite("Create object with many properties");

// ----

bench.add("Create object with 1 prop", () => {
    let opts = {
        prop1: 5
    };
    return opts;
});

bench.add("Create object with 8 prop", () => {
    let opts = {
        prop1: 5,
        prop2: "",
        prop3: false,
        prop4: 1,
        prop5: 0,
        prop6: null,
        prop7: "Hello",
        prop8: 12345
    };
    return opts;
});

bench.add("Create object with 9 prop", () => {
    let opts = {
        prop1: 5,
        prop2: "",
        prop3: false,
        prop4: 1,
        prop5: 0,
        prop6: null,
        prop7: "Hello",
        prop8: 12345,
        prop9: "asd"
    };
    return opts;
});

bench.add("Create object with 20 prop", () => {
    let opts = {
        prop1: 5,
        prop2: "",
        prop3: false,
        prop4: 1,
        prop5: 0,
        prop6: null,
        prop7: "Hello",
        prop8: 12345,
        prop9: "asd",
        prop10: false,
        prop11: 5,
        prop12: "",
        prop13: false,
        prop14: 1,
        prop15: 0,
        prop16: null,
        prop17: "Hello",
        prop18: 12345,
        prop19: "asd",
        prop20: false
    };
    return opts;
});

bench.run();

Solution

  • As far as I know - yes.

    Object in v8 engine has two object representations:

    For new objects V8 engine allocates memory for "FAST 8 properties object" by default which should cover most use cases.

    If the amount of properties exceeds this limit - it rebuild object into more SLOW form, but which allows to have unlimited amount of props inside.

    By the way this doesn't related to the new object instantiation (like new X()): Time from time V8 engine recounts amount of props for new objects(per class/internal type). So if your code creates complex classes - engine will start to create FAST objects with more properties by default for this class/internal type.


    PROOF:

    The details about memory management for V8 engine can be found here http://jayconrod.com/posts/52/a-tour-of-v8-object-representation

    For the new object constructed without a class (like var a = {}) - all properties go to fixed array, called in article "Extra properties"