Skip to content

Commit 5e38565

Browse files
author
Ruben Bridgewater
committed
Improve stringNumbers parsing performance by up to 100%
1 parent 69f78b1 commit 5e38565

File tree

5 files changed

+34
-12
lines changed

5 files changed

+34
-12
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var myParser = new Parser(options);
2929
* `returnError`: *function*; mandatory
3030
* `returnFatalError`: *function*; optional, defaults to the returnError function
3131
* `returnBuffers`: *boolean*; optional, defaults to false
32+
* `stringNumbers`: *boolean*; optional, defaults to false
3233

3334
### Example
3435

@@ -66,7 +67,7 @@ You do not have to use the returnFatalError function. Fatal errors will be retur
6667

6768
And if you want to return buffers instead of strings, you can do this by adding the `returnBuffers` option.
6869

69-
Big numbers that are too large for JS are automatically stringified.
70+
If you handle with big numbers that are to large for JS (Number.MAX_SAFE_INTEGER === 2^53 - 16) please use the `stringNumbers` option. That way all numbers are going to be returned as String and you can handle them safely.
7071

7172
```js
7273
// Same functions as in the first example
@@ -78,7 +79,8 @@ var parser = new Parser({
7879
returnError: function(err) {
7980
lib.returnError(err);
8081
},
81-
returnBuffers: true // All strings are returned as buffer e.g. <Buffer 48 65 6c 6c 6f>
82+
returnBuffers: true, // All strings are returned as Buffer e.g. <Buffer 48 65 6c 6c 6f>
83+
stringNumbers: true // All numbers are returned as String
8284
});
8385

8486
// The streamHandler as above

benchmark/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var startBuffer = new Buffer('$100\r\nabcdefghij')
3434
var chunkBuffer = new Buffer('abcdefghijabcdefghijabcdefghij')
3535
var stringBuffer = new Buffer('+testing a simple string\r\n')
3636
var integerBuffer = new Buffer(':1237884\r\n')
37-
var bigIntegerBuffer = new Buffer(':18446744073709551617\r\n') // 2^64 + 1
37+
var bigIntegerBuffer = new Buffer(':184467440737095516171234567890\r\n') // 2^64 + 1
3838
var errorBuffer = new Buffer('-Error ohnoesitbroke\r\n')
3939
var arrayBuffer = new Buffer('*1\r\n*1\r\n$1\r\na\r\n')
4040
var endBuffer = new Buffer('\r\n')

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## v.2.2.0 - 31 Oct, 2016
2+
3+
Features
4+
5+
- Improve `stringNumbers` parsing performance by up to 100%
6+
17
## v.2.1.1 - 31 Oct, 2016
28

39
Bugfixes

lib/parser.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,40 @@ function parseSimpleNumbers (parser) {
3737

3838
/**
3939
* Used for integer numbers in case of the returnNumbers option
40+
*
41+
* The maximimum possible integer to use is: Math.floor(Number.MAX_SAFE_INTEGER / 10) - 9
42+
*
4043
* @param parser
4144
* @returns {*}
4245
*/
4346
function parseStringNumbers (parser) {
4447
var offset = parser.offset
45-
var length = parser.buffer.length
46-
var number = ''
48+
var length = parser.buffer.length - 1
49+
var number = 0
50+
var res = ''
4751

4852
if (parser.buffer[offset] === 45) {
49-
number += '-'
53+
res += '-'
5054
offset++
5155
}
5256

5357
while (offset < length) {
5458
var c1 = parser.buffer[offset++]
55-
if (c1 === 13 && parser.buffer[offset] === 10) { // \r\n
59+
if (c1 === 13) { // \r\n
5660
parser.offset = offset + 1
57-
return number
61+
if (number !== 0) {
62+
res += number
63+
}
64+
return res
65+
} else if (number > 900719925474090) {
66+
res += number
67+
res += c1 - 48
68+
number = 0
69+
} else if (c1 === 48 && number === 0) {
70+
res += 0
71+
} else {
72+
number = (number * 10) + (c1 - 48)
5873
}
59-
number += c1 - 48
6074
}
6175
}
6276

test/parsers.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ describe('parsers', function () {
541541
return this.skip()
542542
}
543543
var replyCount = 0
544-
var entries = ['123', '590295810358705700002', '-99999999999999999']
544+
var entries = ['123', '590295810358705700002', '-99999999999999999', '9007199254740992', '90071992547409920', '10000040000000000000000000000000000000020']
545545
function checkReply (reply) {
546546
assert.strictEqual(typeof reply, 'string')
547547
assert.strictEqual(reply, entries[replyCount])
@@ -551,8 +551,8 @@ describe('parsers', function () {
551551
returnReply: checkReply,
552552
stringNumbers: true
553553
})
554-
parser.execute(new Buffer(':123\r\n:590295810358705700002\r\n:-99999999999999999\r\n'))
555-
assert.strictEqual(replyCount, 3)
554+
parser.execute(new Buffer(':123\r\n:590295810358705700002\r\n:-99999999999999999\r\n:9007199254740992\r\n:90071992547409920\r\n:10000040000000000000000000000000000000020\r\n'))
555+
assert.strictEqual(replyCount, 6)
556556
})
557557

558558
it('handle big numbers', function () {

0 commit comments

Comments
 (0)