yahoo/express-state — pull request #19 by ericf (2014-01-21 19:48:27+00:00)
Title: Add `cache` option to improve serialization performance

It's common for exposed values to not change during the lifetime of an app or request once they've been passed to the `app.expose()` or `res.expose()` methods. When this is the case, the `cache` option can be set which signals Express State that it's safe to eagerly serialize the value, making repeated calls to `Exposed#toString()` much more efficient.

The most common use case for the `cache` option is for app-level data which doesn't change, like configuration:

```js
app.expose(config, 'app.config', {cache: true});
```

A bug with the parent <- child Exposed instance relationship has also been fixed; the following works as expected:

```js
app.expose('foo', 'window.foo');
console.log(res.locals.state); // => window.foo = "foo";

app.expose('bar', 'window.bar');
console.log(res.locals.state); // => window.foo = "foo";
```

This also brings test coverage back to 100% and adds more code comments.

### Benchmarks

The follow are the benchmarks comparing `master` with this branch.

#### `master`

```
simpleObj:
JSON.stringify( simpleObj ) x 595,990 ops/sec ±3.09% (91 runs sampled)
serialize( simpleObj ) x 280,078 ops/sec ±5.14% (83 runs sampled)
simple.toString() x 233,066 ops/sec ±5.61% (79 runs sampled)

PNM:
pnmApp.toString() x 18,257 ops/sec ±4.58% (86 runs sampled)
pnmRes.toString() x 1,747 ops/sec ±2.71% (91 runs sampled)

YT:
ytApp.toString() x 9,497 ops/sec ±6.10% (83 runs sampled)
ytRes.toString() x 188 ops/sec ±5.44% (76 runs sampled)
```

#### `cache`

```
simpleObj:
JSON.stringify( simpleObj ) x 526,089 ops/sec ±4.64% (82 runs sampled)
serialize( simpleObj ) x 290,813 ops/sec ±3.85% (88 runs sampled)
simple.toString() x 220,056 ops/sec ±3.56% (84 runs sampled)
simpleCached.toString() x 1,972,394 ops/sec ±4.58% (85 runs sampled)

PNM:
pnmApp.toString() x 15,840 ops/sec ±5.44% (84 runs sampled)
pnmAppCached.toString() x 241,270 ops/sec ±4.92% (83 runs sampled)
pnmRes.toString() x 1,427 ops/sec ±5.02% (79 runs sampled)
pnmResAppCached.toString() x 1,737 ops/sec ±3.41% (90 runs sampled)
pnmResCached.toString() x 42,577 ops/sec ±3.44% (88 runs sampled)

YT:
ytApp.toString() x 9,509 ops/sec ±6.08% (85 runs sampled)
ytAppCached.toString() x 339,479 ops/sec ±5.94% (71 runs sampled)
ytRes.toString() x 182 ops/sec ±4.99% (75 runs sampled)
ytResAppCached.toString() x 194 ops/sec ±4.22% (78 runs sampled)
ytResCached.toString() x 29,270 ops/sec ±4.65% (88 runs sampled)
```

### Todos

- [ ] Update docs for cached option
- [ ] Update HISTORY.md
- [ ] Include note about deprecated `expose( obj [, namespace [, local]] )` API