Skip to content

Instantly share code, notes, and snippets.

@thysultan
Last active December 21, 2021 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thysultan/15f645ddcdb5540d0bca2cba5cafd1e4 to your computer and use it in GitHub Desktop.
Save thysultan/15f645ddcdb5540d0bca2cba5cafd1e4 to your computer and use it in GitHub Desktop.
vdom creation #jsbench #jsperf (https://jsbench.github.io/#15f645ddcdb5540d0bca2cba5cafd1e4) #jsbench #jsperf
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>vdom creation #jsbench #jsperf</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script>
<script src="./suite.js"></script>
</head>
<body>
<h1>Open the console to view the results</h1>
<h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2>
</body>
</html>
"use strict";
(function (factory) {
if (typeof Benchmark !== "undefined") {
factory(Benchmark);
} else {
factory(require("benchmark"));
}
})(function (Benchmark) {
var suite = new Benchmark.Suite;
Benchmark.prototype.setup = function () {
'use strict';
var obj = Object;
var arr = Array;
var nop = function(){};
function a (type, value,a,b,c,d,e,f) {'use strict';
var index = 0
var length = a !== undefined ? 3 : 2
var of = value === null || value instanceof obj
var position = of ? 2 : 1
var size = length - position
var identity = 0
var props = of ? value : {}
var children = new arr(size)
if (size > 0) {
if (a !== undefined) {children[0] = a;if (b !== undefined) {children[1] = b;if (c !== undefined) {children[2] = c;}
if (d !== undefined) {children[2] = d;if (e !== undefined) {children[2] = e;if (f !== undefined) {children[2] = f;
if (arguments.length > 8) {
while (position < length) {
children[8+index++] = arguments[8+position++]
}
}
}}}}}
}
switch (typeof type) {
case 'object': identity = 1; children[index] = null
break
case 'function': identity = 2; if (size > 0) props.children = size > 1 ? children : children[0]
}
return {id: identity, type: type, props: props, children: children, own: null}
}
// ------------------
function b (type, props, child) {'use strict';
var index = 0
// var length = arguments.length
// var of = props === null || props instanceof obj
// var position = of ? 2 : 1
// var size = length - position
var identity = 0
var properties = props//of ? props : {}
var children = child
// if (size > 0) {
// for (; position < length; ++position) {
// children[index++] = arguments[position]
// }
// }
var size=arguments.length
if (size > 2) {
if (size > 3) {
children = slice.call(arguments, 2)
}
}
switch (typeof type) {
case 'object':
identity = 1, children[index] = null
break
case 'function':
identity = 2
// if (size > 0) {
// properties.children = size > 1 ? children : children[0]
// }
}
return {id: identity, type: type, props: props, children: children, own: null}
// return new struct(identity, type, properties, children)
// return element.type = type, element
}
function c (type, value,a,b,c,d,e,f) {'use strict';
var index = 0
var length = a !== undefined ? 3 : 2
var of = value === null || value instanceof obj
var position = of ? 2 : 1
var size = length - position
var identity = 0
var props = of ? value : {}
var children = new arr(size)
if (size > 0) {
if (a !== undefined) {children[0] = a;if (b !== undefined) {children[1] = b;if (c !== undefined) {children[2] = c;}
if (d !== undefined) {children[2] = d;if (e !== undefined) {children[2] = e;if (f !== undefined) {children[2] = f;
if (arguments.length > 8) {
while (position < length) {
children[8+index++] = arguments[8+position++]
}
}
}}}}}
}
switch (typeof type) {
case 'object': identity = 1; children[index] = null
break
case 'function': identity = 2; if (size > 0) props.children = size > 1 ? children : children[0]
}
return new Struct(identity, type, props, children)
}
function d (type, value,a,b,c,d,e,f) {'use strict';
var index = 0
var length = a !== undefined ? 3 : 2
var of = props === null || props instanceof obj
var position = of ? 2 : 1
var size = length - position
var identity = 0
var props = of ? value : {}
var children = new arr(size)
if (size > 0) {
if (a !== undefined) {children[0] = a;if (b !== undefined) {children[1] = b;if (c !== undefined) {children[2] = c;}
if (d !== undefined) {children[2] = d;if (e !== undefined) {children[2] = e;if (f !== undefined) {children[2] = f;
if (arguments.length > 8) {
while (position < length) {
children[8+index++] = arguments[8+position++]
}
}
}}}}}
}
switch (typeof type) {
case 'object': identity = 1; children[index] = null
break
case 'function': identity = 2; if (size > 0) props.children = size > 1 ? children : children[0]
}
return new struct(identity, type, props, children)
}
function e (type, value,a) {'use strict';
var index = 0
var length = a !== undefined ? 3 : 2
// var of = value === null || value instanceof obj
// var position = of ? 2 : 1
var size = length// - position
var identity = 0
var props = value
var children
if (size == 3) {
if (a !== undefined) {
children=a;
}
}
switch (typeof type) {
case 'object': identity = 1; //children[index] = null
break
case 'function': identity = 2; if (size > 0) props.children = children
}
return {id: identity, type: type, props: props, children: children, own: null}
}
function struct (id, type, props, children) {'use strict';
this.id = id
this.type = type
this.props = props
this.children = children
this.own = null
// this.key = key
// this.parent = null
// this.context = null
// this.owner = null
// this.value = null
// this.state = null
// this.stack = null
}
struct.prototype={handleEvent:nop}
class Struct {
constructor(id, type, props, children) {'use strict';
this.id = id
this.type = type
this.props = props
this.children = children
this.own = null
}
handleEvent(){}
}
// ----------------------
var data = [null,null,null,null,null,null,null]
// -------------------------------------------------
function createElement(type, props, children) {'use strict';
let normalizedProps = {},
key,
ref,
i;
for (i in props) {
if (i == 'key') key = props[i];
else if (i == 'ref') ref = props[i];
else normalizedProps[i] = props[i];
}
if (arguments.length > 2) {
normalizedProps.children =
arguments.length > 3 ? slice.call(arguments, 2) : children;
}
// If a Component VNode, check for and apply defaultProps
// Note: type may be undefined in development, must never error here.
if (typeof type == 'function' && type.defaultProps != null) {
for (i in type.defaultProps) {
if (normalizedProps[i] === undefined) {
normalizedProps[i] = type.defaultProps[i];
}
}
}
return createVNode(type, normalizedProps, key, ref, null);
}
var options={_catchError:null}
var vnodeId=0
var slice = [].slice;
function createVNode(type, props, key, ref, original) {'use strict';
// V8 seems to be better at detecting type shapes if the object is allocated from the same call site
// Do not inline into createElement and coerceToVNode!
const vnode = {
type,
props,
key,
ref,
_children: null,
_parent: null,
_depth: 0,
_dom: null,
// _nextDom must be initialized to undefined b/c it will eventually
// be set to dom.nextSibling which can return `null` and it is important
// to be able to distinguish between an uninitialized _nextDom and
// a _nextDom that has been set to `null`
_nextDom: undefined,
_component: null,
_hydrating: null,
constructor: undefined,
_original: original == null ? ++vnodeId : original
};
// Only invoke the vnode hook if this was *not* a direct copy:
if (original == null && options.vnode != null) options.vnode(vnode);
return vnode;
}
const REACT_ELEMENT_TYPE = 0
const hasOwnProperty = obj.prototype.hasOwnProperty
const RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true,
};
const ReactElement = function(type, key, ref, self, source, owner, props) {'use strict';
const element = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
};
return element;
};
function jsx(type, config, maybeKey) {
let propName;
// Reserved names are extracted
const props = {};
let key = null;
let ref = null;
// Currently, key can be spread in as a prop. This causes a potential
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
// but as an intermediary step, we will use jsxDEV for everything except
// <div {...props} key="Hi" />, because we aren't currently able to tell if
// key is explicitly declared to be undefined or not.
if (maybeKey !== undefined) {
key = '' + maybeKey;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
if (hasValidRef(config)) {
ref = config.ref;
}
// Remaining properties are added to a new props object
for (propName in config) {
if (
hasOwnProperty.call(config, propName) &&
!RESERVED_PROPS.hasOwnProperty(propName)
) {
props[propName] = config[propName];
}
}
// Resolve default props
if (type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
return ReactElement(
type,
key,
ref,
undefined,
undefined,
null,
props,
);
}
function hasValidRef(config) {'use strict';
return config.ref !== undefined;
}
function hasValidKey(config) {'use strict';
return config.key !== undefined;
}
};
Benchmark.prototype.teardown = function () {
data = data.map(v => {
if (v === undefined) {
throw 'Error'
} else {
return Math.random() > 0.5 ? null : v
}
})
};
suite.add("var value = a('type',{a:1},null) // no-arity, arguments access, pojo", function () {
var value = a('type',{a:1},null) // no-arity, arguments access, pojo
data[0]=value.id
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c?.id : 0;
// }
// data[0] = n;
});
suite.add("var value = b('type',{a:1},null) // strict-arity, arguments access, pojo", function () {
var value = b('type',{a:1},null) // strict-arity, arguments access, pojo
//data[1]=value.id
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c?.id : 0;
// }
// data[1] = n;
});
suite.add("var value = c('type',{a:1},null) // no-arity, arguments access, prototype class", function () {
var value = c('type',{a:1},null) // no-arity, arguments access, prototype class
data[2]=value.id
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c.id : 0;
// }
// data[2] = n;
});
suite.add("var value = d('type',{a:1},null) // no-arity, arguments access, native class", function () {
var value = d('type',{a:1},null) // no-arity, arguments access, native class
data[3]=value.id
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c.id : 0;
// }
// data[3] = n;
});
suite.add("var value = e('type',{a:1},null) // strict-arity, no arguments access, pojo object", function () {
var value = e('type',{a:1},null) // strict-arity, no arguments access, pojo object
data[4]=value.id
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c.id : 0;
// }
// data[4] = n;
});
suite.add("var value = createElement('type',{a:1},null) // preact", function () {
var value = createElement('type',{a:1},null) // preact
data[5]=value._depth
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c.id : 0;
// }
// data[5] = n;
});
suite.add("var value = jsx(\"type\", {a: 1,}); // react new _jsx", function () {
var value = jsx("type", {a: 1,}); // react new _jsx
data[6]=value._owner
// let n = 0;
// for (let c of value.children) {
// n += typeof c === 'object' ? c.id : 0;
// }
// data[6] = n;
});
suite.on("cycle", function (evt) {
console.log(" - " + evt.target);
});
suite.on("complete", function (evt) {
console.log(new Array(30).join("-"));
var results = evt.currentTarget.sort(function (a, b) {
return b.hz - a.hz;
});
results.forEach(function (item) {
console.log((idx + 1) + ". " + item);
});
});
console.log("vdom creation #jsbench #jsperf");
console.log(new Array(30).join("-"));
suite.run();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment