Skip to content

Commit

Permalink
refactor(benchmarks): separate adapters for each library
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenybai committed Mar 15, 2022
1 parent 9a36d1e commit 142619e
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 62 deletions.
35 changes: 18 additions & 17 deletions benchmarks/benchmark.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Benchmark from 'benchmark';
import { VNode } from 'million';
import { h } from 'snabbdom';
import VirtualDom_VNode from 'virtual-dom/vnode/vnode';
import VirtualDom_VText from 'virtual-dom/vnode/vtext';
import { el } from 'simple-virtual-dom';
import _ from 'lodash';

// avoid `Cannot read property 'parentNode' of undefined` error in runScript
Expand All @@ -21,25 +25,22 @@ export const Suite = (name: string, tests: Record<string, Function>) => {
return suite;
};

export const reformatVNode = (vnode: VNode) => {
if (typeof vnode === 'string') return;
if (vnode.key) delete vnode.key;
if (vnode.props === undefined || vnode.props === null) vnode.props = {};
if (vnode.children === undefined || vnode.children === null) vnode.children = [];
if (vnode.children.length > 0) {
vnode.children.forEach(reformatVNode);
}
export const snabbdomAdapter = (vnode: VNode): any => {
if (typeof vnode === 'string') return vnode;
// @ts-ignore
return _.clone(h(vnode.tag, null, vnode.children.map(snabbdomAdapter)));
};

// Virtual DOM libraries like snabbdom, virtual-dom will
// mutate the vnode, even though the vnode must be
// immutable for the benchmark. For this case, we deep
// copy the vnode. This ensures compatibility throughout
// the suite tests.
export const vnodeAdapter = (vnode: VNode): VNode => {
const clonedVNode = _.cloneDeep(vnode);
reformatVNode(clonedVNode);
return clonedVNode;
export const virtualDomAdapter = (vnode: VNode): any => {
if (typeof vnode === 'string') return new VirtualDom_VText(vnode);
// @ts-ignore
return _.clone(new VirtualDom_VNode(vnode.tag, {}, vnode.children.map(virtualDomAdapter)));
};

export const simpleVirtualDomAdapter = (vnode: VNode): any => {
if (typeof vnode === 'string') return vnode;
// @ts-ignore
return _.clone(el(vnode.tag, {}, vnode.children.map(simpleVirtualDomAdapter)));
};

export default benchmark;
13 changes: 8 additions & 5 deletions benchmarks/suites/appendManyRowsToLargeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(10000);
Expand All @@ -33,19 +33,22 @@ const suite = Suite('append many rows to large table (appending 1,000 to a table
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/clearRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(1000);
Expand All @@ -31,19 +31,22 @@ const suite = Suite('clear rows (clearing a table with 1,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/createManyRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(10000);
Expand All @@ -31,19 +31,22 @@ const suite = Suite('create many rows (creating 10,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/createRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(10000);
Expand All @@ -31,19 +31,22 @@ const suite = Suite('create rows (creating 1,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/partialUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(1000);
Expand Down Expand Up @@ -40,19 +40,22 @@ const suite = Suite('partial update (updating every 10th row for 1,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/removeRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement, Deltas } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(1000);
Expand Down Expand Up @@ -43,19 +43,22 @@ const suite = Suite('remove row (removing one row)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/replaceAllRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const shuffleArray = (array: unknown[]) => {
Expand Down Expand Up @@ -46,19 +46,22 @@ const suite = Suite('replace all rows (updating all 1,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
el().childNodes.forEach((tr, i) => {
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/selectRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(1000);
Expand All @@ -33,19 +33,22 @@ const suite = Suite('select row (highlighting a selected row)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
el().childNodes.item(row).style.background = 'red';
Expand Down
13 changes: 8 additions & 5 deletions benchmarks/suites/swapRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createElement, Deltas } from 'packages/million';
import * as simple_virtual_dom from 'simple-virtual-dom';
import * as snabbdom from 'snabbdom';
import * as virtual_dom from 'virtual-dom';
import { Suite, vnodeAdapter } from '../benchmark';
import { simpleVirtualDomAdapter, snabbdomAdapter, Suite, virtualDomAdapter } from '../benchmark';
import { buildData, patch } from '../data';

const data = buildData(1000);
Expand Down Expand Up @@ -47,19 +47,22 @@ const suite = Suite('swap rows (swap 2 rows for table with 1,000 rows)', {
patch(el(), vnode);
},
hundred: () => {
hundred.patch(el(), vnodeAdapter(vnode), vnodeAdapter(oldVNode));
hundred.patch(el(), vnode, oldVNode);
},
'simple-virtual-dom': () => {
const patches = simple_virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = simple_virtual_dom.diff(
simpleVirtualDomAdapter(oldVNode),
simpleVirtualDomAdapter(vnode),
);
simple_virtual_dom.patch(el(), patches);
},
'virtual-dom': () => {
const patches = virtual_dom.diff(vnodeAdapter(oldVNode), vnodeAdapter(vnode));
const patches = virtual_dom.diff(virtualDomAdapter(oldVNode), virtualDomAdapter(vnode));
virtual_dom.patch(el(), patches);
},
snabbdom: () => {
const patch = snabbdom.init([]);
patch(snabbdom.toVNode(el()), vnodeAdapter(vnode));
patch(snabbdom.toVNode(el()), snabbdomAdapter(vnode));
},
DOM: () => {
const elClone = el();
Expand Down

0 comments on commit 142619e

Please sign in to comment.