Closed lawnsea closed 8 years ago
Paging @slimelabs and @lzilioli
@lawnsea I would like to see where this method is going to be used to better assess this PR
I would like to see where this method is going to be used to better assess this PR
@lzilioli it will be used to apply a batch of deferred mounts and unmounts as a single transaction.
I'll add some comments to ensureCloned
to make it more clear what it's up to. I've deferred extensive documentation for this module I hope to land a modified version into object-path-immutable, which currently supports a non-transactional chained syntax.
@lzilioli @slimelabs updated with responses to y'all's feedback
Left some comments, generally looks great. Why the hell doesn't this exist already? Super useful.
@lzilioli @slimelabs I've responded to all outstanding feedback. Any last comments before I land this?
Go pho it
LGTM
As described in #7, repeatedly performing immutable updates can be very slow. One part of the problem is that object-path-immutable doesn't provide a facility for performing multiple operations on an object and then returning a single new object with all affected paths cloned. For example:
Both
foo
andbar
are cloned twice in the above code. What we would like instead is to perform an immutable transaction. This patch implements an API that supports the same operations as object-path-immutable, but performed as a transaction.This is partial progress toward fixing #7.
Benchmark
Code
`quick-benchmark.js`
``` javascript 'use strict'; const immutable = require('object-path-immutable'); const immutableTransaction = require('./lib/object-path-immutable-transaction'); const uuid = require('uuid'); const lorem = require('lorem-ipsum'); const assert = require('assert'); require('console.table'); function hrtimeToMs(hrtime) { return hrtime[0] * 1000 + hrtime[1] / 1e6; } function generateData(N) { const data = []; for (let i = 0; i < N; i++) { data.push({ id: uuid.v4(), value: lorem({ count: 10, units: 'words' }) }); } return data; } function runTrial(initial, data, fn) { const start = process.hrtime(); data.reduce(fn, initial); return hrtimeToMs(process.hrtime(start)); } const original = { foo: { } }; const results = [ 100, 200, 400, 800 ].map(N => { const data = generateData(N); const result = { N }; let control; result['object-path-immutable'] = runTrial(original, data, (o, datum, i) => { o = immutable.set(o, `foo.${datum.id}`, datum.value); if (i === N - 1) { control = o; } return o; }); result['object-path-immutable-transaction'] = runTrial(original, data, (o, datum, i) => { if (i === 0) { o = immutableTransaction(o); } o = o.set(`foo.${datum.id}`, datum.value); if (i === N - 1) { o = o.commit(); assert.deepEqual(control, o); } return o; }); return result; }); console.table(results); ```Results
normalizePath
helperpath[i]
in a variable inensureCloned
ensureCloned
commit