Skip to content

Commit

Permalink
chore: add bench w/ results
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeed committed Feb 4, 2020
1 parent d02290f commit 5053399
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 1 deletion.
50 changes: 50 additions & 0 deletions bench/immutable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const klona = require('klona');
const assert = require('assert');
const { Suite } = require('benchmark');
const dset = require('../dist/dset');

const contenders = {
'clean-set': require('clean-set'),
'dset-klona': function (obj, key, val) {
let copy = klona(obj);
dset(copy, key, val);
return copy;
}
};

console.log('Validation: ');
Object.keys(contenders).forEach(name => {
try {
const input = {};
const output = contenders[name](input, 'x.y.z', 'foobar');

assert.notEqual(output, input, 'new object');
assert.deepStrictEqual(output, {
x: {
y: {
z: 'foobar'
}
}
}, 'expected output');

input.foo = 'bar';
assert.notEqual(output.foo, 'bar', 'detached clone');

console.log(' ✔', name);
} catch (err) {
console.log(' ✘', name, `(FAILED @ "${err.message}")`);
}
});


console.log('\nBenchmark:');
const onCycle = e => console.log(' ' + e.target);
const bench = new Suite({ onCycle });

Object.keys(contenders).forEach(name => {
bench.add(name + ' '.repeat(12 - name.length), () => {
contenders[name]({}, 'x.y.z', 'foobar');
});
});

bench.run();
41 changes: 41 additions & 0 deletions bench/mutable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const assert = require('assert');
const { Suite } = require('benchmark');

const contenders = {
'deep-set': require('deep-set'),
'set-value': require('set-value'),
'lodash/set': require('lodash/set'),
'dset': require('../dist/dset'),
};

console.log('Validation: ');
Object.keys(contenders).forEach(name => {
try {
const input = {};
contenders[name](input, 'x.y.z', 'foobar');
assert.deepStrictEqual(input, {
x: {
y: {
z: 'foobar'
}
}
});

console.log(' ✔', name);
} catch (err) {
console.log(' ✘', name, `(FAILED)`);
}
});


console.log('\nBenchmark:');
const onCycle = e => console.log(' ' + e.target);
const bench = new Suite({ onCycle });

Object.keys(contenders).forEach(name => {
bench.add(name + ' '.repeat(12 - name.length), () => {
contenders[name]({}, 'x.y.z', 'foobar');
});
});

bench.run();
11 changes: 11 additions & 0 deletions bench/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"private": true,
"devDependencies": {
"benchmark": "2.1.4",
"clean-set": "1.1.1",
"deep-set": "1.0.1",
"klona": "1.1.0",
"lodash.set": "4.3.2",
"set-value": "3.0.1"
}
}
35 changes: 35 additions & 0 deletions bench/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Benchmarks – Node.js

Below are the results while running this directory's suites on my machine with Node.js v10.13.0:

#### Mutable

> This is the default (and only) behavior
```
Validation:
✔ deep-set
✔ set-value
✔ lodash/set
✔ dset
Benchmark:
deep-set x 4,130,930 ops/sec ±2.30% (92 runs sampled)
set-value x 4,905,191 ops/sec ±3.03% (91 runs sampled)
lodash/set x 2,566,991 ops/sec ±0.99% (95 runs sampled)
dset x 4,191,060 ops/sec ±0.24% (95 runs sampled)
```

#### Immutable

> This combines `dset` with `klona`, as seen in the main README example
```
Validation:
✔ clean-set
✔ dset-klona
Benchmark:
clean-set x 5,771,347 ops/sec ±0.23% (96 runs sampled)
dset-klona x 3,726,300 ops/sec ±1.53% (93 runs sampled)
```
34 changes: 33 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# dset [![Build Status](https://travis-ci.org/lukeed/dset.svg?branch=master)](https://travis-ci.org/lukeed/dset)

> A tiny (161B) utility for safely writing deep Object values~!
> A tiny (160B) utility for safely writing deep Object values~!
This module exposes two module definitions:

Expand Down Expand Up @@ -48,6 +48,25 @@ console.log(qux);
//=> { a: [{ b: [1, 2] }] }
```

## Mutability

As shown in the examples above, all `dset` interactions mutate the source object.

If you need immutable writes, please visit [`clean-set`](https://github.com/fwilkerson/clean-set) (182B).<br>
Alternatively, you may pair `dset` with [`klona`](https://github.com/lukeed/klona), a 366B utility to clone your source(s). Here's an example pairing:

```js
import klona from 'klona';
import dset from 'dset';

export function deepset(obj, path, val) {
let copy = klona(obj);
dset(copy, path, val);
return copy;
}
```


## API

### dset(obj, path, val)
Expand Down Expand Up @@ -77,6 +96,19 @@ Type: `Any`
The value that you want to set. Can be of any type!


## Benchmarks

For benchmark results, check out the [`bench`](/bench) directory!


## Related

- [dlv](https://github.com/developit/dlv) - safely read from deep properties in 120 bytes
- [dequal](https://github.com/lukeed/dequal) - safely check for deep equality in 247 bytes
- [klona](https://github.com/lukeed/klona) - quickly "deep clone" data in 200 to 330 bytes
- [clean-set](https://github.com/fwilkerson/clean-set) - fast, immutable version of `dset` in 182 bytes


## License

MIT © [Luke Edwards](https://lukeed.com)

0 comments on commit 5053399

Please sign in to comment.