Created
August 5, 2018 09:15
-
-
Save silverwind/7c01043214205af16f0b4679e82008e1 to your computer and use it in GitHub Desktop.
recursive fs.readdir benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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