Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs: Optimizations 3: The Revenge #12105

Closed
wants to merge 15 commits into from
Closed
17 changes: 17 additions & 0 deletions benchmark/fs/read-stream-create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const common = require('../common.js');
const createReadStream = require('fs').createReadStream;

const bench = common.createBenchmark(main, {
n: [2e6]
});

function main(conf) {
var n = +conf.n;

bench.start();
for (var i = 0; i < n; ++i)
createReadStream(null, { fd: 0 });
bench.end(n);
}
49 changes: 49 additions & 0 deletions benchmark/fs/read-stream-throughput-dur.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

if (process.platform === 'win32')
throw new Error('This benchmark is not compatible with Windows');

const common = require('../common.js');
const fs = require('fs');

const bench = common.createBenchmark(main, {
type: ['buf', 'asc', 'utf'],
dur: [5],
size: [1024, 4096, 65535, 1024 * 1024]
});

function main(conf) {
const dur = +conf.dur * 1000;
const hwm = +conf.size;
var bytes = 0;
var encoding;

switch (conf.type) {
case 'buf':
encoding = null;
break;
case 'asc':
encoding = 'ascii';
break;
case 'utf':
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}

setTimeout(() => {
// MB/sec
bench.end(bytes / (1024 * 1024));
process.exit(0);
}, dur);

fs.createReadStream('/dev/zero', {
highWaterMark: hwm,
encoding: encoding
}).on('open', function() {
bench.start();
}).on('data', function(chunk) {
bytes += chunk.length;
});
}
23 changes: 12 additions & 11 deletions benchmark/fs/read-stream-throughput.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
// test the throughput of the fs.WriteStream class.
'use strict';

var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
var filesize = 1000 * 1024 * 1024;
var assert = require('assert');
const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
const fs = require('fs');
const filesize = 1000 * 1024 * 1024;
const assert = require('assert');

var type, encoding, size;
var type;
var encoding;
var size;

var bench = common.createBenchmark(main, {
const bench = common.createBenchmark(main, {
type: ['buf', 'asc', 'utf'],
size: [1024, 4096, 65535, 1024 * 1024]
});
Expand Down Expand Up @@ -53,9 +54,9 @@ function runTest() {
});

rs.on('end', function() {
try { fs.unlinkSync(filename); } catch (e) {}
// MB/sec
bench.end(bytes / (1024 * 1024));
try { fs.unlinkSync(filename); } catch (e) {}
});
}

Expand All @@ -81,7 +82,7 @@ function makeFile() {
function write() {
do {
w--;
} while (false !== ws.write(buf) && w > 0);
} while (ws.write(buf) !== false && w > 0);
if (w === 0)
ws.end();
}
Expand Down
32 changes: 13 additions & 19 deletions benchmark/fs/readfile.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
// Call fs.readFile over and over again really fast.
// Then see how many times it got called.
// Yes, this is a silly benchmark. Most benchmarks are silly.
'use strict';

var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
const fs = require('fs');

var bench = common.createBenchmark(main, {
const bench = common.createBenchmark(main, {
dur: [5],
len: [1024, 16 * 1024 * 1024],
concurrent: [1, 10]
});

function main(conf) {
var len = +conf.len;
const len = +conf.len;
const dur = +conf.dur * 1000;
var cur = +conf.concurrent;
var reads = 0;

try { fs.unlinkSync(filename); } catch (e) {}
var data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
fs.writeFileSync(filename, Buffer.alloc(len, 'x'));

var reads = 0;
var bench_ended = false;
bench.start();
setTimeout(function() {
bench_ended = true;
bench.end(reads);
try { fs.unlinkSync(filename); } catch (e) {}
process.exit(0);
}, +conf.dur * 1000);
}, dur);

function read() {
fs.readFile(filename, afterRead);
Expand All @@ -43,10 +39,8 @@ function main(conf) {
throw new Error('wrong number of bytes returned');

reads++;
if (!bench_ended)
read();
read();
}

var cur = +conf.concurrent;
while (cur--) read();
}
37 changes: 21 additions & 16 deletions benchmark/fs/write-stream-throughput.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// test the throughput of the fs.WriteStream class.
'use strict';

var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
const fs = require('fs');

var bench = common.createBenchmark(main, {
const bench = common.createBenchmark(main, {
dur: [5],
file: [''],
type: ['buf', 'asc', 'utf'],
size: [2, 1024, 65535, 1024 * 1024]
});

function main(conf) {
var dur = +conf.dur;
var type = conf.type;
var size = +conf.size;
const dur = +conf.dur * 1000;
const type = conf.type;
const size = +conf.size;
const file = (conf.file.length === 0 ? filename : conf.file);
var encoding;

var chunk;
Expand All @@ -35,27 +36,31 @@ function main(conf) {
throw new Error('invalid type');
}

try { fs.unlinkSync(filename); } catch (e) {}
try { fs.unlinkSync(file); } catch (e) {}

var started = false;
var ending = false;
var ended = false;
var written = 0;

setTimeout(function() {
ending = true;
f.end();
}, dur * 1000);
}, dur);

var f = fs.createWriteStream(filename);
var f = fs.createWriteStream(file);
f.on('drain', write);
f.on('open', write);
f.on('close', done);
f.on('finish', function() {
ended = true;
var written = fs.statSync(filename).size / 1024;
try { fs.unlinkSync(filename); } catch (e) {}
bench.end(written / 1024);
ended = true;
try { fs.unlinkSync(file); } catch (e) {}
});

function wroteChunk() {
written += size;
}

function write() {
// don't try to write after we end, even if a 'drain' event comes.
Expand All @@ -68,7 +73,7 @@ function main(conf) {
bench.start();
}

while (false !== f.write(chunk, encoding));
while (f.write(chunk, encoding, wroteChunk) !== false);
}

function done() {
Expand Down
75 changes: 75 additions & 0 deletions benchmark/fs/writeFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
const fs = require('fs');
const writeFile = fs.writeFile;

const bench = common.createBenchmark(main, {
dur: [5],
file: [''],
type: ['buf', 'asc', 'utf'],
size: [2, 1024, 64 * 1024, 1024 * 1024]
});

function main(conf) {
const dur = +conf.dur * 1000;
const size = +conf.size;
const file = (conf.file.length === 0 ? filename : conf.file);
var writes = 0;
var ended = false;
var encoding;
var data;

try { fs.unlinkSync(file); } catch (e) {}
process.on('exit', function() {
try { fs.unlinkSync(file); } catch (e) {}
});

setTimeout(function() {
bench.end(writes);
ended = true;
}, dur);

switch (conf.type) {
case 'buf':
data = Buffer.alloc(size, 'b');
(function() {
function afterWrite(err) {
if (err)
throw err;
if (ended)
return;
++writes;
writeFile(file, data, afterWrite);
}
bench.start();
writeFile(file, data, afterWrite);
})();
return;
case 'asc':
data = new Array(size + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
data = new Array(Math.ceil(size / 2) + 1).join('ü');
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}

(function() {
function afterWrite(err) {
if (err)
throw err;
if (ended)
return;
++writes;
writeFile(file, data, encoding, afterWrite);
}
bench.start();
writeFile(file, data, encoding, afterWrite);
})();
}
53 changes: 53 additions & 0 deletions benchmark/fs/writeFileSync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

const path = require('path');
const common = require('../common.js');
const filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
const fs = require('fs');
const writeFileSync = fs.writeFileSync;

const bench = common.createBenchmark(main, {
n: [1e5],
file: [''],
type: ['buf', 'asc', 'utf'],
size: [2, 1024, 64 * 1024, 1024 * 1024]
});

function main(conf) {
const n = +conf.n;
const size = +conf.size;
const file = (conf.file.length === 0 ? filename : conf.file);
var encoding;
var data;
var i;

try { fs.unlinkSync(file); } catch (e) {}
process.on('exit', function() {
try { fs.unlinkSync(file); } catch (e) {}
});

switch (conf.type) {
case 'buf':
data = Buffer.alloc(size, 'b');
bench.start();
for (i = 0; i < n; ++i)
writeFileSync(file, data);
bench.end(n);
return;
case 'asc':
data = new Array(size + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
data = new Array(Math.ceil(size / 2) + 1).join('ü');
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}

bench.start();
for (i = 0; i < n; ++i)
writeFileSync(file, data, encoding);
bench.end(n);
}
Loading