forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
buffer: floating point read/write improvements
Improvements: * floating point operations are approx 4x's faster * Now write quiet NaN's * all read/write on floating point now done in C, so no more need for lib/buffer_ieee754.js * float values have more accurate min/max value checks * add additional benchmarks for buffers read/write * created benchmark/_bench_timer.js which is a simple library that can be included into any benchmark and provides an intelligent tracker for sync and async tests * add benchmarks for DataView set methods * add checks and tests to make sure offset is greater than 0
- Loading branch information
1 parent
eef0ccb
commit 22b84e6
Showing
13 changed files
with
633 additions
and
255 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* This is a simple addition to allow for higher resolution timers. | ||
* It can be used to track time for both synchronous or asynchronous | ||
* calls. For synchronous calls pass a callback function like so: | ||
* | ||
* var timer = require('./_bench_timer'); | ||
* | ||
* timer('myTest', function() { | ||
* for (var i = 0; i < 1e6; i++) | ||
* // ... run something here | ||
* } | ||
* }); | ||
* | ||
* For asynchronous timers just pass the name. Then run it again with | ||
* the same name to finish it: | ||
* | ||
* timer('checkAsync'); | ||
* setTimeout(function() { | ||
* timer('checkAsync'); | ||
* }, 300); | ||
* | ||
* When this happens all currently queued benchmarks will be paused | ||
* until the asynchronous benchmark has completed. | ||
* | ||
* If the benchmark has been run with --expose_gc then the garbage | ||
* collector will be run between each test. | ||
* | ||
* The setTimeout delay can also be changed by passing a value to | ||
* timer.delay. | ||
*/ | ||
|
||
|
||
var store = {}; | ||
var order = []; | ||
var maxLength = 0; | ||
var processing = false; | ||
var asyncQueue = 0; | ||
var GCd = typeof gc !== 'function' ? false : true; | ||
|
||
function timer(name, fn) { | ||
if (maxLength < name.length) | ||
maxLength = name.length; | ||
if (!fn) { | ||
processing = false; | ||
if (!store[name]) { | ||
asyncQueue++; | ||
store[name] = process.hrtime(); | ||
return; | ||
} | ||
displayTime(name, process.hrtime(store[name])); | ||
asyncQueue--; | ||
} else { | ||
store[name] = fn; | ||
order.push(name); | ||
} | ||
if (!processing && asyncQueue <= 0) { | ||
processing = true; | ||
setTimeout(run, timer.delay); | ||
} | ||
} | ||
|
||
timer.delay = 100; | ||
|
||
function run() { | ||
if (asyncQueue > 0 || order.length <= 0) | ||
return; | ||
if (GCd) gc(); | ||
setTimeout(function() { | ||
var name = order.shift(); | ||
var fn = store[name]; | ||
var ini = process.hrtime(); | ||
fn(); | ||
ini = process.hrtime(ini); | ||
displayTime(name, ini); | ||
run(); | ||
}, timer.delay); | ||
} | ||
|
||
function displayTime(name, ini) { | ||
name += ': '; | ||
while (name.length < maxLength + 2) | ||
name += ' '; | ||
console.log(name + '%s \u00b5s', | ||
(~~((ini[0] * 1e6) + (ini[1] / 1e3))) | ||
.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")); | ||
} | ||
|
||
module.exports = timer; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const LEN = 1e7; | ||
const noAssert = process.argv[3] == 'true' ? true | ||
: process.argv[3] == 'false' ? false | ||
: undefined; | ||
|
||
var timer = require('./_bench_timer'); | ||
|
||
var buff = (process.argv[2] == 'slow') ? | ||
(new require('buffer').SlowBuffer(8)) : | ||
(new Buffer(8)); | ||
var i; | ||
|
||
buff.writeDoubleLE(0, 0, noAssert); | ||
|
||
timer('readUInt8', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readUInt8(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readUInt16LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readUInt16LE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readUInt16BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readUInt16BE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readUInt32LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readUInt32LE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readUInt32BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readUInt32BE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readInt8', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readInt8(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readInt16LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readInt16LE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readInt16BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readInt16BE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readInt32LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readInt32LE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readInt32BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readInt32BE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readFloatLE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readFloatLE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readFloatBE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readFloatBE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readDoubleLE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readDoubleLE(0, noAssert); | ||
} | ||
}); | ||
|
||
timer('readDoubleBE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.readDoubleBE(0, noAssert); | ||
} | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
const LEN = 1e7; | ||
|
||
const INT8 = 0x7f; | ||
const INT16 = 0x7fff; | ||
const INT32 = 0x7fffffff; | ||
const UINT8 = INT8 * 2; | ||
const UINT16 = INT16 * 2; | ||
const UINT32 = INT32 * 2; | ||
|
||
const noAssert = process.argv[3] == 'true' ? true | ||
: process.argv[3] == 'false' ? false | ||
: undefined; | ||
|
||
var timer = require('./_bench_timer'); | ||
|
||
var buff = (process.argv[2] == 'slow') ? | ||
(new require('buffer').SlowBuffer(8)) : | ||
(new Buffer(8)); | ||
var i; | ||
|
||
timer('writeUInt8', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeUInt8(i % UINT8, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeUInt16LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeUInt16LE(i % UINT16, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeUInt16BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeUInt16BE(i % UINT16, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeUInt32LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeUInt32LE(i % UINT32, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeUInt32BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeUInt32BE(i % UINT32, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeInt8', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeInt8(i % INT8, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeInt16LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeInt16LE(i % INT16, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeInt16BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeInt16BE(i % INT16, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeInt32LE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeInt32LE(i % INT32, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeInt32BE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeInt32BE(i % INT32, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeFloatLE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeFloatLE(i * 0.1, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeFloatBE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeFloatBE(i * 0.1, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeDoubleLE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeDoubleLE(i * 0.1, 0, noAssert); | ||
} | ||
}); | ||
|
||
timer('writeDoubleBE', function() { | ||
for (i = 0; i < LEN; i++) { | ||
buff.writeDoubleBE(i * 0.1, 0, noAssert); | ||
} | ||
}); |
Oops, something went wrong.