Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Create object with 1 prop 0% (62,695,620 rps) (avg: 15ns)
  • Create object with 8 prop -31.95% (42,662,752 rps) (avg: 23ns)
  • Create object with 9 prop -95.79% (2,640,046 rps) (avg: 378ns)

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:

  • Windows_NT 6.1.7601 x64
  • Node.JS: 6.9.5
  • V8: 5.1.281.89
  • Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz × 4

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();
like image 450
Icebob Avatar asked Jan 04 '23 04:01

Icebob


1 Answers

As far as I know - yes.

Object in v8 engine has two object representations:

  • fast with limited amount of props
  • slow with unlimited props

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"

Engine allocates space for 8 elements in fixed array by default

After fixed array is full - object is rebuilt into dictionary here

Prototypes and system objects are always FAST, they use different rebuilding procedure when fixed array is full.

like image 177
Andrii Muzalevskyi Avatar answered Jan 06 '23 19:01

Andrii Muzalevskyi