Skip to content

Commit

Permalink
⚡ Add setDeepProp in benchmark (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlepage committed Jan 22, 2019
1 parent e8cda33 commit 64a63ec
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/immutadot-benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"devDependencies": {
"cross-env": "~5.2.0",
"immer": "~1.8.0",
"immer": "~1.10.5",
"immutable": "~4.0.0-rc.12",
"immutadot": "~2.0.0",
"jest": "~21.2.1",
Expand Down
31 changes: 22 additions & 9 deletions packages/immutadot-benchmark/src/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,32 @@ export class BenchmarkSuite {
function run(key, operation) {
const startTime = Date.now()
const maxTimeMs = Math.round(maxTime * 1000)

const startingTime = maxTimeMs / 100 // Starting time is a hundredth of max time
let startingIterations = 1
let startingOperations = 0

while (Date.now() - startTime < startingTime) {
let iterations = startingIterations
startingIterations *= 2
startingOperations += iterations

while (iterations--) operation()
}

const maxRunTime = Math.round(maxTimeMs / 10) // Max run time is a tenth of max time
const limitEndTime = startTime + maxTimeMs

let iterations = 1 // Start with 1 iteration
const getIterations = (measuredOperations, measuredTime) => Math.min(
// Either enough operations to consume max run time or remaining time
Math.ceil(Math.min(maxRunTime, Math.max(limitEndTime - Date.now(), 0)) / (measuredTime / measuredOperations)),
// Or enough operations to reach max operations
maxOperations - measuredOperations,
)

let nbOperations = 0
let totalTime = 0
let iterations = getIterations(startingOperations, Date.now() - startTime)

while (iterations > 0) {
nbOperations += iterations
Expand All @@ -34,14 +54,7 @@ export class BenchmarkSuite {
while (iterations--) operation()
totalTime += Date.now() - runStartTime

const tempMeanTime = totalTime / nbOperations

iterations = Math.min(
// Either enough operations to consume max run time or remaining time
Math.ceil(Math.min(maxRunTime, Math.max(limitEndTime - Date.now(), 0)) / tempMeanTime),
// Or enough operations to reach max operations
maxOperations - nbOperations,
)
iterations = getIterations(nbOperations, totalTime)
}

if (typeof testResult === 'function') testResult(key, operation())
Expand Down
4 changes: 3 additions & 1 deletion packages/immutadot-benchmark/src/benchmark.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-env jest */
import { BenchmarkSuite } from './benchmark'
import { setDeepProp } from './setDeepProp'
import { setProp } from './setProp'
import { updateTodos } from './updateTodos'

Expand All @@ -9,7 +10,7 @@ const benchmarkSuite = new BenchmarkSuite(
['es2015', 'ES2015 destructuring'],
['immutable', 'immutable 3.8.2'],
['seamless', 'seamless-immutable 7.1.3'],
['immer', 'immer 1.2.0'],
['immer', 'immer 1.10.5'],
['qim', 'qim 0.0.52'],
['immutadot', 'immutad●t 2.0.0'],
['qim-curried', 'qim 0.0.52 curried'],
Expand All @@ -19,6 +20,7 @@ const benchmarkSuite = new BenchmarkSuite(

describe('Benchmark suite', () => {
describe('Set a property', () => setProp(benchmarkSuite))
describe('Set a deeply nested property', () => setDeepProp(benchmarkSuite))
describe('Update small todos list', () => updateTodos(benchmarkSuite, 'Update small todos list (1000 items)', 1000, 100, 30, 50000))
describe('Update medium todos list', () => updateTodos(benchmarkSuite, 'Update medium todos list (10000 items)', 10000, 1000, 30, 5000))
describe('Update large todos list', () => updateTodos(benchmarkSuite, 'Update large todos list (100000 items)', 100000, 10000, 30, 500))
Expand Down
211 changes: 211 additions & 0 deletions packages/immutadot-benchmark/src/setDeepProp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/* eslint-env jest */
import * as qim from 'qim'
import immer, { setAutoFreeze } from 'immer'
import Immutable from 'immutable'
import Seamless from 'seamless-immutable/seamless-immutable.production.min'
import { set } from 'immutadot/core'

export function setDeepProp(benchmarkSuite) {
// Prepare base state
const baseState = {
nested1: {
arr1: [
{
nested2: {
arr2: [
{
nested3: {
arr3: [
{
nested4: {
arr4: [
{
nested5: {
arr5: [
{
nested6: {
arr6: [
{
prop: 'foo',
otherProp: 'aze',
},
],
otherProp: 'aze6',
},
},
],
otherProp: 'aze5',
},
},
],
otherProp: 'aze4',
},
},
],
otherProp: 'aze3',
},
},
],
otherProp: 'aze2',
},
},
],
otherProp: 'aze1',
},
other: { prop: 'baz' },
}

// Prepare immutable state
const immutableState = Immutable.fromJS(baseState)

// Prepare seamless state
const seamlessState = Seamless.from(baseState)

// Disable immer auto freeze
setAutoFreeze(false)

const benchmark = benchmarkSuite.createBenchmark(
'Set a deeply nested property',
(key, result) => {
if (key === 'immutable') return
expect(result).toEqual({
nested1: {
arr1: [
{
nested2: {
arr2: [
{
nested3: {
arr3: [
{
nested4: {
arr4: [
{
nested5: {
arr5: [
{
nested6: {
arr6: [
{
prop: 'bar',
otherProp: 'aze',
},
],
otherProp: 'aze6',
},
},
],
otherProp: 'aze5',
},
},
],
otherProp: 'aze4',
},
},
],
otherProp: 'aze3',
},
},
],
otherProp: 'aze2',
},
},
],
otherProp: 'aze1',
},
other: { prop: 'baz' },
})
},
10,
5000000,
)

it('es2015', () => {
benchmark('es2015', () => {
return {
...baseState,
nested1: {
...baseState.nested1,
arr1: [{
...baseState.nested1.arr1[0],
nested2: {
...baseState.nested1.arr1[0].nested2,
arr2: [{
...baseState.nested1.arr1[0].nested2.arr2[0],
nested3: {
...baseState.nested1.arr1[0].nested2.arr2[0].nested3,
arr3: [{
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0],
nested4: {
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4,
arr4: [{
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0],
nested5: {
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5,
arr5: [{
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0],
nested6: {
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0].nested6,
arr6: [{
...baseState.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0].nested6.arr6[0],
prop: 'bar',
}],
},
}],
},
}],
},
}],
},
}],
},
}],
},
}
})
})

it('immutable', () => {
benchmark('immutable', () => {
immutableState.setIn(['nested1', 'arr1', 0, 'nested2', 'arr2', 0, 'nested3', 'arr3', 0, 'nested4', 'arr4', 0, 'nested5', 'arr5', 0, 'nested6', 'arr6', 0, 'prop'], 'bar')
})
})

it('seamless', () => {
benchmark('seamless', () => {
return Seamless.setIn(seamlessState, ['nested1', 'arr1', 0, 'nested2', 'arr2', 0, 'nested3', 'arr3', 0, 'nested4', 'arr4', 0, 'nested5', 'arr5', 0, 'nested6', 'arr6', 0, 'prop'], 'bar')
})
})

it('immer', () => {
benchmark('immer', () => {
return immer(baseState, draft => {
draft.nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0].nested6.arr6[0].prop = 'bar'
})
})
})

it('qim', () => {
benchmark('qim', () => {
return qim.set(['nested1', 'arr1', 0, 'nested2', 'arr2', 0, 'nested3', 'arr3', 0, 'nested4', 'arr4', 0, 'nested5', 'arr5', 0, 'nested6', 'arr6', 0, 'prop'], 'bar', baseState)
})
})

it('immutad●t', () => {
benchmark('immutadot', () => {
return set(baseState, 'nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0].nested6.arr6[0].prop', 'bar')
})
})

it('qim curried', () => {
benchmark('qim-curried', () => {
return qim.set(['nested1', 'arr1', 0, 'nested2', 'arr2', 0, 'nested3', 'arr3', 0, 'nested4', 'arr4', 0, 'nested5', 'arr5', 0, 'nested6', 'arr6', 0, 'prop'])('bar')(baseState)
})
})

it('immutad●t curried', () => {
benchmark('immutadot-curried', () => {
return set('nested1.arr1[0].nested2.arr2[0].nested3.arr3[0].nested4.arr4[0].nested5.arr5[0].nested6.arr6[0].prop')('bar')(baseState)
})
})
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4163,10 +4163,10 @@ ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==

immer@~1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/immer/-/immer-1.8.0.tgz#afa8393996a1f3f5255019e7d10c29d42dd95225"
integrity sha512-zOox8DNAunPeQgKwbAiwEUAHhZXtMPZo7VZ7m7h9cpQL1I35bAeaxMfwYyLEIt6RZUelFfsOBfG1GJu/iQNgxw==
immer@~1.10.5:
version "1.10.5"
resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.5.tgz#a4fd1d12587a166da769763f881c0039fa61c557"
integrity sha512-5z/nKfF1GQoLCt2JraST2PFkUTwegZDUX3+dd0u2xD2IVxFAbXCZDvWnG8KtxXoqLzRSTqTpf8s/8bXkZE61xA==

immutable@~4.0.0-rc.12:
version "4.0.0-rc.12"
Expand Down

0 comments on commit 64a63ec

Please sign in to comment.