Skip to content

Commit

Permalink
Better benchmark and handling of strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcollina committed Aug 6, 2016
1 parent 55b3c4b commit d9b0821
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 46 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
# fast-json-stringify  [![Build Status](https://travis-ci.org/mcollina/fast-json-stringify.svg)](https://travis-ci.org/mcollina/fast-json-stringify)

__fast-json-stringify__ is x5 faster than `JSON.stringify()`.
__fast-json-stringify__ is x1-5 times faster than `JSON.stringify()`.
It is particularly suited if you are sending small JSON payloads, the
advantages reduces on large payloads.

Benchmarks:

```
JSON.stringify x 1,681,132 ops/sec ±0.59% (88 runs sampled)
fast-json-stringify x 5,117,658 ops/sec ±1.44% (87 runs sampled)
JSON.stringify array x 3,500 ops/sec ±0.91% (85 runs sampled)
fast-json-stringify array x 4,456 ops/sec ±1.68% (87 runs sampled)
JSON.stringify long string x 13,395 ops/sec ±0.88% (91 runs sampled)
fast-json-stringify long string x 95,488 ops/sec ±1.04% (90 runs sampled)
JSON.stringify short string x 5,059,316 ops/sec ±0.86% (92 runs sampled)
fast-json-stringify short string x 12,219,967 ops/sec ±1.16% (91 runs sampled)
JSON.stringify obj x 1,763,980 ops/sec ±1.30% (88 runs sampled)
fast-json-stringify obj x 5,085,148 ops/sec ±1.56% (89 runs sampled)
```

## Example
Expand Down
72 changes: 38 additions & 34 deletions bench.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const benchmark = require('benchmark')
const safeStringify = require('fast-safe-stringify')
const suite = new benchmark.Suite()

const schema = {
Expand Down Expand Up @@ -34,36 +33,25 @@ const obj = {
age: 32
}

const multiArray = [
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj,
obj
]
const multiArray = []

const stringify = require('.')(schema)
const stringifyArray = require('.')(arraySchema)
const stringifyString = require('.')({ type: 'string' })
var str = ''

suite.add('JSON.stringify', function () {
JSON.stringify(obj)
})
for (var i = 0; i < 10000; i++) {
str += i
if (i % 100 === 0) {
str += '"'
}
}

suite.add('fast-json-stringify', function () {
stringify(obj)
})
Number(str)

suite.add('fast-safe-stringify', function () {
safeStringify(obj)
})
for (i = 0; i < 1000; i++) {
multiArray.push(obj)
}

suite.add('JSON.stringify array', function () {
JSON.stringify(multiArray)
Expand All @@ -73,18 +61,34 @@ suite.add('fast-json-stringify array', function () {
stringifyArray(multiArray)
})

suite.add('fast-safe-stringify array', function () {
safeStringify(multiArray)
suite.add('JSON.stringify long string', function () {
JSON.stringify(str)
})

suite.on('complete', print)
suite.add('fast-json-stringify long string', function () {
stringifyString(str)
})

suite.run()
suite.add('JSON.stringify short string', function () {
JSON.stringify('hello world')
})

function print () {
for (var i = 0; i < this.length; i++) {
console.log(this[i].toString())
}
suite.add('fast-json-stringify short string', function () {
stringifyString('hello world')
})

suite.add('JSON.stringify obj', function () {
JSON.stringify(obj)
})

suite.add('fast-json-stringify obj', function () {
stringify(obj)
})

suite.on('cycle', cycle)

suite.run()

console.log('Fastest is', this.filter('fastest').map('name')[0])
function cycle (e) {
console.log(e.target.toString())
}
46 changes: 37 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ function build (schema) {
'use strict'
${$asString.toString()}
${$asStringSmall.toString()}
${$asStringLong.toString()}
${$asNumber.toString()}
${$asNull.toString()}
${$asBoolean.toString()}
Expand Down Expand Up @@ -65,27 +67,51 @@ function $asBoolean (bool) {

function $asString (str) {
if (str instanceof Date) {
str = str.toISOString()
} else {
return '"' + str.toISOString() + '"'
} else if (typeof str !== 'string') {
str = str.toString()
}

if (str.length < 42) {
return $asStringSmall(str)
} else {
return $asStringLong(str)
}
}

function $asStringLong (str) {
var result = ''
var last = 0
var l = str.length
var i

while ((i = str.indexOf('"')) >= 0 && i < l) {
result += str.slice(last, i) + '\\"'
last = i + 1
for (;(i = str.indexOf('"')) >= 0 && i < l;) {
result += str.slice(0, i) + '\\"'
str = str.slice(i + 1)
l = str.length
}

if (l > 0) {
result += str
}

return '"' + result + '"'
}

function $asStringSmall (str) {
var result = ''
var last = 0
var l = str.length
for (var i = 0; i < l; i++) {
if (str[i] === '"') {
result += str.slice(last, i) + '\\"'
last = i + 1
}
}
if (last === 0) {
result = str
} else {
result += str.slice(last)
}

return '"' + result + '"'
}

Expand Down Expand Up @@ -134,9 +160,11 @@ function buildArray (schema, code, name) {
const result = nested(laterCode, name, '[i]', schema.items)

code += `
for (var i = 0; i < obj.length; i++) {
const l = obj.length
const w = l - 1
for (var i = 0; i < l; i++) {
${result.code}
if (i < obj.length - 1) {
if (i < w) {
json += ','
}
}
Expand Down
5 changes: 5 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ buildTest({
type: 'string'
}, 'hello world')

buildTest({
title: 'string with quotes',
type: 'string'
}, 'hello """" world')

buildTest({
title: 'boolean true',
type: 'boolean'
Expand Down

0 comments on commit d9b0821

Please sign in to comment.