summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2013-09-09 19:39:21 -0700
committerTrevor Norris <trev.norris@gmail.com>2013-09-09 19:39:21 -0700
commit59dac01e4eaebd01714b6640ae2cd656796147fb (patch)
treea9d5243004fc75daabf9df4bff4c933baf3bca36 /lib
parent204228b57f06ece34b61d69c5e3b58218bbfed0e (diff)
downloadnode-new-59dac01e4eaebd01714b6640ae2cd656796147fb.tar.gz
buffer: optimize common encoding cases
String#toLowerCase() is incredibly slow and was costing a 15-30% performance hit for Buffers less than 1KB. Now instead it'll attempt to find the correct encoding directly from the passed encoding, only then afterwards it'll lowercase. The optimization for not passing any encoding at all is still at the top of the method. At most this may add 10% performance hit for passing a mixed case encoding.
Diffstat (limited to 'lib')
-rw-r--r--lib/buffer.js50
1 files changed, 28 insertions, 22 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index dfd79e6290..de0ab040dd 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -202,40 +202,46 @@ Buffer.prototype.parent = undefined;
// toString(encoding, start=0, end=buffer.length)
Buffer.prototype.toString = function(encoding, start, end) {
- encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
+ var loweredCase = false;
- start = ~~start;
- end = util.isUndefined(end) ? this.length : ~~end;
+ start = start >>> 0;
+ end = util.isUndefined(end) ? this.length : end >>> 0;
+ if (!encoding) encoding = 'utf8';
if (start < 0) start = 0;
if (end > this.length) end = this.length;
if (end <= start) return '';
- switch (encoding) {
- case 'hex':
- return this.hexSlice(start, end);
+ while (true) {
+ switch (encoding) {
+ case 'hex':
+ return this.hexSlice(start, end);
- case 'utf8':
- case 'utf-8':
- return this.utf8Slice(start, end);
+ case 'utf8':
+ case 'utf-8':
+ return this.utf8Slice(start, end);
- case 'ascii':
- return this.asciiSlice(start, end);
+ case 'ascii':
+ return this.asciiSlice(start, end);
- case 'binary':
- return this.binarySlice(start, end);
+ case 'binary':
+ return this.binarySlice(start, end);
- case 'base64':
- return this.base64Slice(start, end);
+ case 'base64':
+ return this.base64Slice(start, end);
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return this.ucs2Slice(start, end);
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return this.ucs2Slice(start, end);
- default:
- throw new TypeError('Unknown encoding: ' + encoding);
+ default:
+ if (loweredCase)
+ throw new TypeError('Unknown encoding: ' + encoding);
+ encoding = (encoding + '').toLowerCase();
+ loweredCase = true;
+ }
}
};