- Revision
- 99879
- Author
- [email protected]
- Date
- 2011-11-10 10:39:39 -0800 (Thu, 10 Nov 2011)
Log Message
[MutationObservers] Microbenchmarks for appendChild, removeChild, and innerHTML
https://bugs.webkit.org/show_bug.cgi?id=71939
Reviewed by Ojan Vafai.
These benchmarks time both the DOM mutations themselves and the time taken
to call the MutationCallback. This measurement is achieved by
executing the code entirely within the MutationCallback itself.
* Mutation/append-child-deep.html: Added. Covers appendChild in a 200-node-deep tree with subtree observation.
* Mutation/append-child.html: Added. Covers appendChild in a flat tree.
* Mutation/inner-html.html: Added. Covers innerHTML adding and removing many nodes at a time.
* Mutation/remove-child-deep.html: Added. Covers removeChild in a 200-node-deep tree with subtree observation.
* Mutation/remove-child.html: Added. Covers removeChild in a flat tree.
Modified Paths
Added Paths
Diff
Modified: trunk/PerformanceTests/ChangeLog (99878 => 99879)
--- trunk/PerformanceTests/ChangeLog 2011-11-10 18:36:12 UTC (rev 99878)
+++ trunk/PerformanceTests/ChangeLog 2011-11-10 18:39:39 UTC (rev 99879)
@@ -1,3 +1,20 @@
+2011-11-09 Adam Klein <[email protected]>
+
+ [MutationObservers] Microbenchmarks for appendChild, removeChild, and innerHTML
+ https://bugs.webkit.org/show_bug.cgi?id=71939
+
+ Reviewed by Ojan Vafai.
+
+ These benchmarks time both the DOM mutations themselves and the time taken
+ to call the MutationCallback. This measurement is achieved by
+ executing the code entirely within the MutationCallback itself.
+
+ * Mutation/append-child-deep.html: Added. Covers appendChild in a 200-node-deep tree with subtree observation.
+ * Mutation/append-child.html: Added. Covers appendChild in a flat tree.
+ * Mutation/inner-html.html: Added. Covers innerHTML adding and removing many nodes at a time.
+ * Mutation/remove-child-deep.html: Added. Covers removeChild in a 200-node-deep tree with subtree observation.
+ * Mutation/remove-child.html: Added. Covers removeChild in a flat tree.
+
2011-10-25 Adam Barth <[email protected]>
EventTargetFactory.in is not sorted
Added: trunk/PerformanceTests/Mutation/append-child-deep.html (0 => 99879)
--- trunk/PerformanceTests/Mutation/append-child-deep.html (rev 0)
+++ trunk/PerformanceTests/Mutation/append-child-deep.html 2011-11-10 18:39:39 UTC (rev 99879)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<body>
+<pre id="log"></pre>
+<script src=""
+<div id="sandbox" style="display:none"></div>
+<script>
+var sandbox = document.getElementById('sandbox');
+var node = sandbox;
+for (var i = 0; i < 200; ++i)
+ node = node.appendChild(document.createElement('div'));
+var elems = [];
+for (var i = 0; i < 50000; ++i)
+ elems[i] = document.createElement('div');
+var observing = false;
+
+var observer = new WebKitMutationObserver(listener);
+var tickledSpan = document.createElement('span');
+observer.observe(tickledSpan, {attributes: true});
+
+function resetState() {
+ window.start = null;
+ window.numRuns = 25;
+ window.times = [];
+}
+
+function runAgain() {
+ tickledSpan.setAttribute('data-foo', numRuns);
+}
+
+function listener(mutations) {
+ if (start) {
+ var time = Date.now() - start;
+ times.push(time);
+ log(time);
+ }
+ if (numRuns-- >= 0) {
+ runAgain();
+ if (observing)
+ observer.disconnect()
+ node.innerHTML = '';
+ if (observing)
+ observer.observe(sandbox, {childList: true, subtree: true});
+ start = Date.now();
+ for (var i = 0; i < elems.length; ++i)
+ node.appendChild(elems[i]);
+ } else {
+ logStatistics(times);
+ if (!observing) {
+ observing = true;
+ resetState();
+ log('\n------------\n');
+ log('Running ' + numRuns + ' times with observation');
+ setTimeout(runAgain, 0);
+ }
+ }
+}
+
+resetState();
+log('Running ' + numRuns + ' times without observation');
+window.addEventListener('load', runAgain);
+</script>
+</body>
Property changes on: trunk/PerformanceTests/Mutation/append-child-deep.html
___________________________________________________________________
Added: svn:eol-style
Added: trunk/PerformanceTests/Mutation/append-child.html (0 => 99879)
--- trunk/PerformanceTests/Mutation/append-child.html (rev 0)
+++ trunk/PerformanceTests/Mutation/append-child.html 2011-11-10 18:39:39 UTC (rev 99879)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<body>
+<pre id="log"></pre>
+<script src=""
+<div id="sandbox" style="display:none"></div>
+<script>
+var sandbox = document.getElementById('sandbox');
+var observing = false;
+
+var elems = [];
+for (var i = 0; i < 50000; ++i)
+ elems[i] = document.createElement('div');
+var observer = new WebKitMutationObserver(listener);
+var tickledSpan = document.createElement('span');
+observer.observe(tickledSpan, {attributes: true});
+
+function resetState() {
+ window.start = null;
+ window.numRuns = 25;
+ window.times = [];
+}
+
+function runAgain() {
+ tickledSpan.setAttribute('data-foo', numRuns);
+}
+
+function listener(mutations) {
+ if (start) {
+ var time = Date.now() - start;
+ times.push(time);
+ log(time);
+ }
+ if (numRuns-- >= 0) {
+ runAgain();
+ if (observing)
+ observer.disconnect()
+ sandbox.innerHTML = '';
+ if (observing)
+ observer.observe(sandbox, {childList: true});
+ start = Date.now();
+ for (var i = 0; i < elems.length; ++i)
+ sandbox.appendChild(elems[i]);
+ } else {
+ logStatistics(times);
+ if (!observing) {
+ observing = true;
+ resetState();
+ log('\n------------\n');
+ log('Running ' + numRuns + ' times with observation');
+ setTimeout(runAgain, 0);
+ }
+ }
+}
+
+resetState();
+log('Running ' + numRuns + ' times without observation');
+window.addEventListener('load', runAgain);
+</script>
+</body>
Property changes on: trunk/PerformanceTests/Mutation/append-child.html
___________________________________________________________________
Added: svn:eol-style
Added: trunk/PerformanceTests/Mutation/inner-html.html (0 => 99879)
--- trunk/PerformanceTests/Mutation/inner-html.html (rev 0)
+++ trunk/PerformanceTests/Mutation/inner-html.html 2011-11-10 18:39:39 UTC (rev 99879)
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<body>
+<pre id="log"></pre>
+<script src=""
+<div id="sandbox" style="display:none"></div>
+<script>
+var sandbox = document.getElementById('sandbox');
+var observing = false;
+for (var i = 0; i < 1000; ++i)
+ sandbox.appendChild(document.createElement('div'));
+var html = sandbox.innerHTML;
+
+var observer = new WebKitMutationObserver(listener);
+var tickledSpan = document.createElement('span');
+observer.observe(tickledSpan, {attributes: true});
+
+function resetState() {
+ window.start = null;
+ window.numRuns = 25;
+ window.times = [];
+}
+
+function runAgain() {
+ tickledSpan.setAttribute('data-foo', numRuns);
+}
+
+function listener(mutations) {
+ if (start) {
+ var time = Date.now() - start;
+ times.push(time);
+ log(time);
+ }
+ if (numRuns-- >= 0) {
+ runAgain();
+ start = Date.now();
+ for (var i = 0; i < 100; ++i)
+ sandbox.innerHTML = html;
+ } else {
+ logStatistics(times);
+ if (!observing) {
+ observer.observe(sandbox, {childList: true});
+ observing = true;
+ resetState();
+ log('\n------------\n');
+ log('Running ' + numRuns + ' times with observation');
+ setTimeout(runAgain, 0);
+ }
+ }
+}
+
+resetState();
+log('Running ' + numRuns + ' times without observation');
+window.addEventListener('load', runAgain);
+</script>
+</body>
Property changes on: trunk/PerformanceTests/Mutation/inner-html.html
___________________________________________________________________
Added: svn:eol-style
Added: trunk/PerformanceTests/Mutation/remove-child-deep.html (0 => 99879)
--- trunk/PerformanceTests/Mutation/remove-child-deep.html (rev 0)
+++ trunk/PerformanceTests/Mutation/remove-child-deep.html 2011-11-10 18:39:39 UTC (rev 99879)
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<body>
+<pre id="log"></pre>
+<script src=""
+<div id="sandbox" style="display:none"></div>
+<script>
+var sandbox = document.getElementById('sandbox');
+var node = sandbox;
+for (var i = 0; i < 200; ++i)
+ node = node.appendChild(document.createElement('div'));
+var observing = false;
+
+var observer = new WebKitMutationObserver(listener);
+var tickledSpan = document.createElement('span');
+observer.observe(tickledSpan, {attributes: true});
+
+function resetState() {
+ window.start = null;
+ window.numRuns = 25;
+ window.times = [];
+}
+
+function runAgain() {
+ tickledSpan.setAttribute('data-foo', numRuns);
+}
+
+function hideFromObservation(func) {
+ if (observing)
+ observer.disconnect();
+ func();
+ if (observing)
+ observer.observe(sandbox, {childList: true, subtree: true});
+}
+
+function listener(mutations) {
+ if (start) {
+ var time = Date.now() - start;
+ times.push(time);
+ log(time);
+ }
+ if (numRuns-- >= 0) {
+ runAgain();
+ hideFromObservation(function() {
+ for (var i = 0; i < 50000; ++i)
+ node.appendChild(document.createElement('div'));
+ });
+ start = Date.now();
+ while (node.firstChild)
+ node.removeChild(node.firstChild);
+ } else {
+ logStatistics(times);
+ if (!observing) {
+ observing = true;
+ resetState();
+ log('\n------------\n');
+ log('Running ' + numRuns + ' times with observation');
+ setTimeout(runAgain, 0);
+ }
+ }
+}
+
+resetState();
+log('Running ' + numRuns + ' times without observation');
+window.addEventListener('load', runAgain);
+</script>
+</body>
Property changes on: trunk/PerformanceTests/Mutation/remove-child-deep.html
___________________________________________________________________
Added: svn:eol-style
Added: trunk/PerformanceTests/Mutation/remove-child.html (0 => 99879)
--- trunk/PerformanceTests/Mutation/remove-child.html (rev 0)
+++ trunk/PerformanceTests/Mutation/remove-child.html 2011-11-10 18:39:39 UTC (rev 99879)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<body>
+<pre id="log"></pre>
+<script src=""
+<div id="sandbox" style="display:none"></div>
+<script>
+var sandbox = document.getElementById('sandbox');
+var observing = false;
+
+var observer = new WebKitMutationObserver(listener);
+var tickledSpan = document.createElement('span');
+observer.observe(tickledSpan, {attributes: true});
+
+function resetState() {
+ window.start = null;
+ window.numRuns = 25;
+ window.times = [];
+}
+
+function runAgain() {
+ tickledSpan.setAttribute('data-foo', numRuns);
+}
+
+function hideFromObservation(func) {
+ if (observing)
+ observer.disconnect()
+ func();
+ if (observing)
+ observer.observe(sandbox, {childList: true});
+}
+
+function listener(mutations) {
+ if (start) {
+ var time = Date.now() - start;
+ times.push(time);
+ log(time);
+ }
+ if (numRuns-- >= 0) {
+ runAgain();
+ hideFromObservation(function() {
+ for (var i = 0; i < 50000; ++i)
+ sandbox.appendChild(document.createElement('div'));
+ });
+ start = Date.now();
+ while (sandbox.firstChild)
+ sandbox.removeChild(sandbox.firstChild);
+ } else {
+ logStatistics(times);
+ if (!observing) {
+ observer.observe(sandbox, {childList: true});
+ observing = true;
+ resetState();
+ log('\n------------\n');
+ log('Running ' + numRuns + ' times with observation');
+ setTimeout(runAgain, 0);
+ }
+ }
+}
+
+resetState();
+log('Running ' + numRuns + ' times without observation');
+window.addEventListener('load', runAgain);
+</script>
+</body>
Property changes on: trunk/PerformanceTests/Mutation/remove-child.html
___________________________________________________________________
Added: svn:eol-style