Skip to content

Instantly share code, notes, and snippets.

@silverwind
Created August 5, 2018 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silverwind/7c01043214205af16f0b4679e82008e1 to your computer and use it in GitHub Desktop.
Save silverwind/7c01043214205af16f0b4679e82008e1 to your computer and use it in GitHub Desktop.
recursive fs.readdir benchmark
"use strict";
const fs = require("fs");
const util = require("util");
const p = process.argv[2];
function time() {
const t = process.hrtime();
return Math.round((t[0] * 1e9 + t[1]) / 1e6);
}
const walk = function(dir, cb) {
let files = [], dirs = [];
fs.readdir(dir, (_, entries) => {
(function next(i) {
if (!entries || !entries[i]) return cb(null, [dirs, files]);
const path = dir + "/" + entries[i];
fs.stat(path, (_, stat) => {
if (stat && stat.isDirectory()) {
dirs.push(path);
walk(path, (d, f) => {
dirs = dirs.concat(d);
files = files.concat(f);
next(++i);
});
} else {
files.push(path);
next(++i);
}
});
})(0);
});
};
const walkSync = function(dir) {
let files = [], dirs = [];
const entries = fs.readdirSync(dir);
for (let i = 0, l = entries.length; i < l; i++) {
const path = dir + "/" + entries[i];
const stat = fs.statSync(path);
if (stat.isDirectory()) {
dirs.push(path);
const r = walkSync(path);
dirs = dirs.concat(r[1]);
files = files.concat(r[2]);
} else {
files.push(path);
}
}
return [dirs, files];
};
const walkNew = function(dir, cb) {
let files = [], dirs = [];
fs.readdir(dir, {withFileTypes: true}, (_, entries) => {
(function next(i) {
if (!entries || !entries[i]) return cb(null, [dirs, files]);
const path = dir + "/" + entries[i].name;
if (entries[i].isDirectory()) {
dirs.push(path);
walkNew(path, (d, f) => {
dirs = dirs.concat(d);
files = files.concat(f);
next(++i);
});
} else {
files.push(path);
next(++i);
}
})(0);
});
};
const walkNewSync = function(dir) {
let files = [], dirs = [];
const entries = fs.readdirSync(dir, {withFileTypes: true});
for (let i = 0, l = entries.length; i < l; i++) {
const path = dir + "/" + entries[i].name;
if (entries[i].isDirectory()) {
dirs.push(path);
const r = walkNewSync(path);
dirs = dirs.concat(r[1]);
files = files.concat(r[2]);
} else {
files.push(path);
}
}
return [dirs, files];
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function run(fn, name) {
await util.promisify(fs.writeFile)("/proc/sys/vm/drop_caches", "3", () => {});
await sleep(5000);
const start = time();
await fn(p);
console.log(name, time() - start, "ms");
}
(async () => {
await run(walkSync, "readdir sync");
await run(util.promisify(walk), "readdir async");
await run(walkNewSync, "readdir withFileTypes sync");
await run(util.promisify(walkNew), "readdir withFileTypes async");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment