diff --git a/benchmark/d8_benchmark.js b/benchmark/d8_benchmark.js new file mode 100644 index 0000000..2a35ce5 --- /dev/null +++ b/benchmark/d8_benchmark.js @@ -0,0 +1,34 @@ +var testDiv = document.createElement('div'); +var width = 2; +var depth = 4; +var decoration = 8; +var instanceCount = 10; +var oneTime = true; +var compoundBindings = false; +var expressionCheckbox = false; +var bindingDensities = [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]; +var testTypes = ['MDV']; + +function benchmarkComplete(results) { + print('benchmarkComplete'); + print(JSON.stringify(results)); +} + +function updateStatus(density, testType, runCount) { + print('updateStatus'); + print(testType + ' ' + (100 * density) + + '% binding density, ' + runCount + ' runs'); +} + +var test = new MDVBenchmark(testDiv, width, depth, decoration, instanceCount, + oneTime, + compoundBindings, + expressionCheckbox); + +var runner = new BenchmarkRunner(test, + bindingDensities, + testTypes, + benchmarkComplete, + updateStatus); +runner.go(); +runTimeouts(); diff --git a/benchmark/dom.js b/benchmark/dom.js new file mode 100644 index 0000000..025792c --- /dev/null +++ b/benchmark/dom.js @@ -0,0 +1,364 @@ +var console = { + log: print, + error: print +}; + +var timeouts = [] +function setTimeout(fn) { + timeouts.push(fn); +} + +function runTimeouts() { + while (timeouts.length) { + if (Object.deliverAllChangeRecords) + Object.deliverAllChangeRecords(); + timeouts.shift()(); + } +} + +function Window() {} + +var window = new Window(); + +function Event(type) { + this.type = type; +} +Event.prototype = { + initMouseEvent: function() {} +} + +function Node(owner) { + this.ownerDocument = owner; + this.parentNode = null; + this.nextSibling = null; + this.previousSibling = null; + this.firstChild = null; + this.lastChild = null; +} +Node.prototype = { + addEventListener: function() {}, + set textContent(content) { + this.data = content; + }, + get textContent() { + return this.data; + }, + dispatchEvent: function() {}, + appendChild: function(node) { + if (node instanceof DocumentFragment) { + while (node.firstChild) { + this.appendChild(node.firstChild); + } + + return; + } + + if (node.parentNode) { + node.parentNode.removeChild(node); + } + + node.parentNode = this; + if (!this.firstChild) { + this.firstChild = node; + this.lastChild = node; + } else { + this.lastChild.nextSibling = node; + node.previousSibling = this.lastChild; + this.lastChild = node; + } + return node; + }, + + removeChild: function(node) { + if (node.parentNode != this) + return; + if (!node.previousSibling && !node.nextSibling) { + this.firstChild = null; + this.lastChild = null; + } else if (!node.previousSibling) { + this.firstChild = node.nextSibling; + node.nextSibling.previousSibling = null; + } else if (!node.nextSibling) { + this.lastChild = node.previousSibling; + node.previousSibling.nextSibling = null; + } else { + node.previousSibling.nextSibling = node.nextSibling; + node.nextSibling.previousSibling = node.previousSibling; + } + + node.parentNode = null; + node.previousSibling = null; + node.nextSibling = null; + }, + insertBefore: function(node, otherNode) { + if (node.parentNode) + node.parentNode.removeChild(node); + if (node instanceof DocumentFragment) { + while (node.firstChild) { + this.insertBefore(node.firstChild, otherNode); + } + return node; + } + if (!otherNode || otherNode.parentNode !== this) + return this.appendChild(node); + if (!otherNode.previousSibling) { + otherNode.previousSibling = node; + node.previousSibling = null; + node.nextSibling = otherNode; + this.firstChild = node; + } else { + otherNode.previousSibling.nextSibling = node; + node.previousSibling = node.previousSibling; + node.nextSibling = otherNode; + otherNode.previousSibling = node; + } + node.parentNode = this; + return node; + }, + cloneNode: function(deep) { + var clone = this.cloneNode_(); + if (deep) { + for (var child = this.firstChild; child; child = child.nextSibling) { + var c = child.cloneNode(deep); + clone.appendChild(c); + } + } + return clone; + }, + + get childNodes() { + var retval = []; + for (var child = this.firstChild; child; child = child.nextSibling) + retval.push(child); + return retval; + }, + + set innerHTML() { + while (this.firstChild) { + this.removeChild(this.firstChild); + } + }, + + dump: function(pre) { + var prefix = ''; + for (var i = 0; i < pre; i++) + prefix += ' '; + print(prefix + this.toString()); + for (var child = this.firstChild; child; child = child.nextSibling) + child.dump(pre + 2); + } +} + +Node.ELEMENT_NODE = 1; +Node.TEXT_NODE = 3; +Node.DOCUMENT_FRAGMENT_NODE = 11; +Node.DOCUMENT_NODE = 9; + +function Document(defaultView) { + Node.call(this, null); + this.defaultView = defaultView; + this.templateContentsOwnerDocument = defaultView ? new Document() : this; +} +Document.prototype = { + __proto__: Node.prototype, + nodeType: Node.DOCUMENT_NODE, + implementation: { + createHTMLDocument: function() { + return new Document(); + } + }, + importNode: function(node) { + var clone = node.cloneNode(false); + clone.ownerDocument = this; + return clone; + }, + createElement: function(tagName) { + var n = this.createElement_(tagName); + return n; + }, + createElement_: function(tagName) { + tagName = tagName.toUpperCase(); + switch(tagName) { + case 'DIV': + return new HTMLDivElement(this, tagName); + case 'INPUT': + return new HTMLInputElement(this, tagName); + case 'P': + return new HTMLParagraphElement(this, tagName); + case 'SPAN': + return new HTMLSpanElement(this, tagName); + case 'H1': + case 'H2': + return new HTMLHeadingElement(this, tagName); + case 'TEMPLATE': + return new HTMLTemplateElement(this, tagName); + default: + throw Error('Unknown tag: ' + tagName); + } + }, + createEvent: function(type) { + return new Event(type); + }, + createDocumentFragment: function() { + return new DocumentFragment(); + }, + createTextNode: function(data) { + return new Text(this, data); + } +} +var document = new Document(window); + +function DocumentFragment(owner) { + Node.call(this, owner); +} +DocumentFragment.prototype = { + __proto__: Node.prototype, + nodeType: Node.DOCUMENT_FRAGMENT_NODE, + cloneNode_: function() { + return new DocumentFragment(this.ownerDocument); + }, + toString: function() { + return '#document-fragment'; + }, + querySelectorAll: function() { + return []; + } +}; + + +function Text(owner, data) { + Node.call(this, owner); + this.data = data; +} +Text.prototype = { + __proto__: Node.prototype, + nodeType: Node.TEXT_NODE, + cloneNode_: function() { + return new Text(this.ownerDocument, this.data); + }, + toString: function() { + return '#text: ' + this.data; + } +}; + +function Element(owner, tagName) { + Node.call(this, owner); + this.tagName = tagName; + this.attributes = []; +}; + +Element.prototype = { + __proto__: Node.prototype, + nodeType: Node.ELEMENT_NODE, + cloneNode_: function() { + var c = this.ownerDocument.createElement(this.tagName); + for (var i = 0; i < this.attributes.length; i++) + c.attributes.push(this.attributes[i]); + return c; + }, + setAttribute: function(name, value) { + this.attributes.push({ name: name, value: value }); + }, + getAttribute: function(name) { + var count = this.attributes.length; + while (count-- > 0) { + if (this.attributes[count].name === name) + return this.attributes[count].value; + } + return null; + }, + hasAttribute: function(name) { + var count = this.attributes.length; + while (count-- > 0) { + if (this.attributes[count].name === name) + return true; + } + + return false; + }, + toString: function() { + var string = '<' + this.tagName + '>['; + var attrs = {}; + var count = this.attributes.length; + while (count-- > 0) { + var attr = this.attributes[count]; + if (attrs[attr.name]) + continue; + string += attr.name + '=' + attr.value + ', '; + attrs[attr.name] = true; + } + string += ']'; + return string; + }, +}; + +function HTMLElement(owner, tagName) { + Element.call(this, owner, tagName); +} +HTMLElement.prototype = { + __proto__: Element.prototype +}; + +function HTMLDivElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLDivElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLInputElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLInputElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLTextAreaElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLTextAreaElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLOptionElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLOptionElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLSelectElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLSelectElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLParagraphElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLParagraphElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLSpanElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLSpanElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLHeadingElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); +} +HTMLHeadingElement.prototype = { + __proto__: HTMLElement.prototype +}; + +function HTMLTemplateElement(owner, tagName) { + HTMLElement.call(this, owner, tagName); + this.content = new DocumentFragment(); +} +HTMLTemplateElement.prototype = { + __proto__: HTMLElement.prototype +};