Skip to content

Instantly share code, notes, and snippets.

@vigneshshanmugam
Last active March 17, 2020 14:52
Show Gist options
  • Save vigneshshanmugam/c766550ecd02292dcdfbf0bf013b9d3d to your computer and use it in GitHub Desktop.
Save vigneshshanmugam/c766550ecd02292dcdfbf0bf013b9d3d to your computer and use it in GitHub Desktop.
Object.keys benchmark in v8

Before

Code

const types = {};
const typeSymbols = t => {
  // don't recompute
  if (Object.keys(types).length < 1) {
    t.TYPES.forEach(type => {
      types[type] = Symbol.for(type);
    });
  }
  return types;
};

Runtime call stats

                      Runtime Function/C++ Builtin        Time             Count
========================================================================================
                                      JS_Execution  14927.84ms  64.79%       780   0.01%
                                                GC   4689.46ms  20.35%      6173   0.06%
                              RecompileSynchronous    554.43ms   2.41%      1421   0.01%
                                  KeyedGetProperty    528.23ms   2.29%   3933063  36.63%
                                      **ObjectKeys    313.81ms   1.36%     35271   0.33%**
                                       ArrayConcat    271.53ms   1.18%    588038   5.48%
                                       StringSplit    251.53ms   1.09%   1751662  16.31%
                                 WeakCollectionSet    239.46ms   1.04%    523176   4.87%
                                  FunctionCallback    114.92ms   0.50%      7327   0.07%
                              ParseFunctionLiteral     92.11ms   0.40%      4991   0.05%
                                       SetProperty     80.53ms   0.35%    272005   2.53%
                                        ArrayShift     67.56ms   0.29%    439602   4.09%

After

const types = {};
// This is a test key which is used to avoid Object.keys check
// Object.keys() check is really expensive for some reason
const testKey = "Expression";
const typeSymbols = t => {
  // don't recompute
  if (types[testKey] === undefined) {
    t.TYPES.forEach(type => {
      types[type] = Symbol.for(type);
    });
  }
  return types;
};

                      Runtime Function/C++ Builtin        Time             Count
========================================================================================
                                      JS_Execution  14642.71ms  65.47%       780   0.01%
                                                GC   4743.74ms  21.21%      6123   0.06%
                              RecompileSynchronous    551.68ms   2.47%      1419   0.01%
                                  KeyedGetProperty    486.89ms   2.18%   3918491  36.87%
                                       ArrayConcat    267.63ms   1.20%    587895   5.53%
                                       StringSplit    237.34ms   1.06%   1711960  16.11%
                                 WeakCollectionSet    236.57ms   1.06%    522817   4.92%
                              ParseFunctionLiteral     94.73ms   0.42%      4990   0.05%
                                       SetProperty     86.13ms   0.39%    271994   2.56%
                                        ArrayShift     65.48ms   0.29%    439682   4.14%
                                       StringEqual     58.63ms   0.26%    758386   7.14%
                                        ArraySlice     58.63ms   0.26%    277773   2.61%
                                        ....
                                       **ObjectKeys      7.72ms   0.03%     13549   0.13%**

@vigneshshanmugam
Copy link
Author

vigneshshanmugam commented Jan 5, 2018

Believe this is obvious and its a bad choice to use Object.keys in the hot path.

Results

object-keys: 249.800ms
test-key: 2.990ms

sample-test.js

const dummmyArr = Array.from({ length: 100 }, (d, i) => i + "");
const noOfTimes = 1e5;
let types = {};

const explode = () => {
  if (Object.keys(types).length < 1) {
    dummmyArr.forEach(type => {
      types[type] = Symbol.for(type);
    });
  }
};

console.time("types");
for (let i = 0; i < noOfTimes; i++) {
  explode();
}
console.timeEnd("types");

let types2 = {};
let testKey = "1";
const explode2 = () => {
  if (types2[testKey] === undefined) {
    dummmyArr.forEach(type => {
      types2[type] = Symbol.for(type);
    });
  }
};

console.time("types2");
for (let i = 0; i < noOfTimes; i++) {
  explode2();
}
console.timeEnd("types2");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment