Skip to content

Instantly share code, notes, and snippets.

@ahmedengu
Created July 18, 2020 14:41
Show Gist options
  • Save ahmedengu/ffd052a4d312399bd9c6272f64927867 to your computer and use it in GitHub Desktop.
Save ahmedengu/ffd052a4d312399bd9c6272f64927867 to your computer and use it in GitHub Desktop.
20X performance improvement on Nodejs, just by caching process.env with a single line: process.env = JSON.parse(JSON.stringify(process.env));
// ****************************
//* ********* OUTPUT **********
//* **** 20X Improvement ******
//* ******** Tested on ********
//* ****** Node v10.14.2 ******
// ****************************
// Start testing : Original
// Original, #0: 1299.590ms
// Original, #1: 1268.201ms
// Original, #2: 1261.733ms
// Original, #3: 1262.137ms
// Original, #4: 1277.845ms
// Original total: 6372.165ms
// process.env.OS: Windows_NT
//
// ****************************
// Caching: 0.312ms
// ****************************
//
// Start testing : Cached
// Cached, #0: 43.721ms
// Cached, #1: 44.087ms
// Cached, #2: 44.561ms
// Cached, #3: 43.703ms
// Cached, #4: 43.713ms
// Cached total: 219.999ms
// process.env.OS: Windows_NT
// ****************************
// benchmark process.env
function benchmark(label, iterations = 5, accessTimes = 10 * 1000 * 1000) {
let os; let i; let j;
console.log(`Start testing : ${label}`);
// total timer
console.time(`${label} total`);
// run 5 iterations, each with 10m env access
for (i = 0; i < iterations; i += 1) {
// iteration timer
console.time(`${label}, #${i}`);
for (j = 0; j < accessTimes; j += 1) {
os = process.env.OS;
}
console.timeEnd(`${label}, #${i}`);
}
console.timeEnd(`${label} total`);
// just make sure we are accessing a valid value
console.log('process.env.OS: ', os);
}
// benchmark the original process.env
benchmark('Original');
console.log('\n****************************');
console.time('Caching'); // how long the caching takes
// cache process.env, to override native getters
process.env = JSON.parse(JSON.stringify(process.env));
console.timeEnd('Caching');
console.log('****************************\n');
// benchmark the cached version
benchmark('Cached');
Copy link

ghost commented Jul 18, 2020

Hello What Is This For

@ahmedengu
Copy link
Author

ahmedengu commented Jul 18, 2020

Hello @DevPreston1,

This optimization can be used for NodeJs applications that use process.env heavily,
Such as checking the env for every client request,

process.env is a live object that make use of underlying c++ getters to resolve the env var you are looking for, which is quite costly:
https://github.com/nodejs/node-v0.x-archive/blob/b922b5e/src/node.cc#L2326-L2335

So with simple caching we can improve the performance of such application 20X (in terms of accessing the env) using:
process.env = JSON.parse(JSON.stringify(process.env));

New versions of node seem to optimize for this, but it wouldn't hurt using with older Node versions:
nodejs/node#3104 (comment)

Its not quite known, this is the only result that i can find that use this approach:
nodejs/node#3104 (comment)
facebook/react#812 (comment)

Best Regards,
Ahmed

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