Permalink
Browse files

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 22b84e6216b86f9d5178e7d8a4d1a577209b7008 @trevnorris trevnorris committed with isaacs Dec 22, 2012
View
32 LICENSE
@@ -252,38 +252,6 @@ maintained libraries. The externally maintained libraries used by Node are:
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
-- lib/buffer_ieee754.js. Its license follows:
- """
- // Copyright (c) 2008, Fair Oaks Labs, Inc.
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // * Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Redistributions in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors
- // may be used to endorse or promote products derived from this software
- // without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- """
-
- lib/punycode.js is copyright 2011 Mathias Bynens <http://mathiasbynens.be/>
and released under the MIT license.
"""
View
@@ -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;
View
@@ -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);
+ }
+});
View
@@ -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.

0 comments on commit 22b84e6

Please sign in to comment.