1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 // DOMWalk - a benchmark for walking the DOM 32 // 33 // This benchmark tests different mechanisms for touching every element 34 // in a section of the DOM. The elements are created from JavaScript causing 35 // them to be pre-wrapped. 36 // 37 // Tests small iterations and large iterations to see if there is a difference. 38 39 40 // We use two mechanisms to walk the DOM, and then 41 // verify that both yield the same result. 42 var __num_nodes = 0; 43 44 // We create a table to iterate as part of this test. 45 // For now it's just a big table with lots of elements. 46 function DOMWalk_CreateTable(height, width) { 47 var table = document.getElementById("fake_dom"); 48 if (table) { 49 // clear out existing table 50 while (table.rows.length > 0) 51 table.deleteRow(0); 52 } else { 53 var doc = document; 54 table = doc.createElement("table"); 55 table.id = "fake_dom"; 56 table.border = 1; 57 58 for (var row = 0; row < height; row++) { 59 var row_object = doc.createElement("tr"); 60 for (var column = 0; column < width; column++) { 61 var col_object = doc.createElement("td"); 62 var text = document.createTextNode(row.toString() + "." + column.toString()); 63 col_object.appendChild(text); 64 row_object.appendChild(col_object); 65 } 66 table.appendChild(row_object); 67 } 68 var content = document.getElementById("benchmark_content"); 69 content.appendChild(table); 70 var html = content.innerHTML; 71 var width = content.clientWidth; 72 } 73 return table; 74 } 75 76 function DOMWalk_SetupSmall() { 77 // Creates a table with 100 nodes. 78 DOMWalk_CreateTable(10, 10); 79 } 80 81 function DOMWalk_SetupLarge() { 82 // Creates a table with 4000 nodes. 83 DOMWalk_CreateTable(200, 200); 84 } 85 86 // Walks the DOM via getElementsByTagName. 87 function DOMWalk_ByTagName(table) { 88 var items = table.getElementsByTagName("*"); 89 var item; 90 var length = items.length; 91 for (var index = 0; index < length; index++) 92 item = items[index]; 93 94 // Return the number of nodes seen. 95 return items.length; 96 } 97 98 function DOMWalk_ByTagNameDriver(loops) { 99 var table = document.getElementById("benchmark_content"); 100 for (var loop = 0; loop < loops; loop++) 101 __num_nodes = DOMWalk_ByTagName(table); 102 } 103 104 function DOMWalk_ByTagNameSmall() { 105 // This test runs in a short time. We loop a few times in order to avoid small time measurements. 106 DOMWalk_ByTagNameDriver(1000); 107 } 108 109 function DOMWalk_ByTagNameLarge() { 110 DOMWalk_ByTagNameDriver(1); 111 } 112 113 function DOMWalk_Recursive(node) { 114 // Count Element Nodes only. 115 // IE does not define the Node constants. 116 var count = (node.nodeType == /* Node.ELEMENT_NODE */ 1) ? 1 : 0; 117 118 var child = node.firstChild; 119 while (child !== null) { 120 count += DOMWalk_Recursive(child); 121 child = child.nextSibling; 122 } 123 124 return count; 125 } 126 127 // Walks the DOM via a recursive walk 128 function DOMWalk_RecursiveDriver(loops) { 129 var table = document.getElementById("benchmark_content"); 130 for (var loop = 0; loop < loops; loop++) { 131 var count = DOMWalk_Recursive(table) - 1; // don't count the root node. 132 if (count != __num_nodes || count === 0) 133 throw "DOMWalk failed! Expected " + __num_nodes + " nodes but found " + count + "."; 134 } 135 } 136 137 function DOMWalk_RecursiveSmall() { 138 // This test runs in a short time. We loop a few times in order to avoid small time measurements. 139 DOMWalk_RecursiveDriver(200); 140 } 141 142 function DOMWalk_RecursiveLarge() { 143 // Only iterate once over the large DOM structures. 144 DOMWalk_RecursiveDriver(1); 145 } 146 147 148 var DOMWalkTest = new BenchmarkSuite('DOMWalk', [ 149 new Benchmark("DOMWalkByTag (100 nodes)", DOMWalk_ByTagNameSmall, DOMWalk_SetupSmall), 150 new Benchmark("DOMWalkRecursive (100 nodes)", DOMWalk_RecursiveSmall, DOMWalk_SetupSmall), 151 new Benchmark("DOMWalkByTag (4000 nodes)", DOMWalk_ByTagNameLarge, DOMWalk_SetupLarge), 152 new Benchmark("DOMWalkRecursive (4000 nodes)", DOMWalk_RecursiveLarge, DOMWalk_SetupLarge) 153 ]); 154