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 // DOMTable - a benchmark creating tables and accessing table elements 32 // 33 // This benchmark tests different mechanisms for creating an HTML table. By 34 // either creating the DOM elements individually or by creating an inner HTML 35 // as a string. The effect of forcing a layout is also measured. 36 // A second part of the benchmark sums the contents of all elements. Again 37 // in one set the benchmark is created using DOM functions from JavaScript, 38 // causing all nodes to be prewrapped, while in a second set the table is 39 // created using inner HTML which will wrap the elements at access. 40 41 // Size of the created tables. 42 var DOMTable_maxRows = 100; 43 var DOMTable_maxCols = 40; 44 45 // Helper variable to create consistent values for the table elements. 46 var DOMTable_element_count = 0; 47 48 // Functions needed to create a table by creating individual DOM elements. 49 function DOMTable_CreateCell(row_id, col_id) { 50 var cell = document.createElement("td"); 51 cell.id = "$" + row_id + "$" + col_id; 52 cell.textContent = DOMTable_element_count++; 53 return cell; 54 } 55 56 function DOMTable_CreateRow(row_id, cols) { 57 var row = document.createElement("tr"); 58 for (var i = 0; i < cols; i++) 59 row.appendChild(DOMTable_CreateCell(row_id, i)); 60 return row; 61 } 62 63 function DOMTable_CreateTable(rows, cols) { 64 var table = document.createElement("table"); 65 for (var i = 0; i < rows; i++) 66 table.appendChild(DOMTable_CreateRow(i, cols)); 67 return table; 68 } 69 70 // Functions needed to create a table by creating a big piece of HTML in a 71 // single string. 72 function DOMTable_CreateCellIH(row_id, col_id) { 73 return '<td id="$' + row_id + '$' + col_id + '">' + DOMTable_element_count++ + '</td>'; 74 } 75 76 function DOMTable_CreateRowIH(row_id, cols) { 77 var html_string = '<tr>'; 78 for (var i = 0; i < cols; i++) 79 html_string += DOMTable_CreateCellIH(row_id, i); 80 return html_string + '</tr>'; 81 } 82 83 function DOMTable_CreateTableIH(rows, cols) { 84 var html_string = '<table>'; 85 for (var i = 0; i < rows; i++) 86 html_string += DOMTable_CreateRowIH(i, cols); 87 return html_string + '</table>'; 88 } 89 90 91 // Shared setup function for all table creation tests. 92 function DOMTable_CreateSetup() { 93 DOMTable_element_count = 0; 94 return document.getElementById("benchmark_content"); 95 } 96 97 function DOMTable_Create(root_element) { 98 // Create the table and add it to the root_element for the benchmark. 99 root_element.appendChild(DOMTable_CreateTable(DOMTable_maxRows, DOMTable_maxCols)); 100 return root_element; 101 } 102 103 function DOMTable_CreateLayout(root_element) { 104 // Create the table and add it to the root_element for the benchmark. 105 root_element.appendChild(DOMTable_CreateTable(DOMTable_maxRows, DOMTable_maxCols)); 106 // Force a layout by requesting the height of the table. The result is 107 // going to be ignored because there is not cleanup function registered. 108 return root_element.scrollHeight; 109 } 110 111 function DOMTable_InnerHTML(root_element) { 112 // Create the HTML string for the table and set it at the root_element for the benchmark. 113 root_element.innerHTML = DOMTable_CreateTableIH(DOMTable_maxRows, DOMTable_maxCols); 114 return root_element; 115 } 116 117 function DOMTable_InnerHTMLLayout(root_element) { 118 // Create the HTML string for the table and set it at the root_element for the benchmark. 119 root_element.innerHTML = DOMTable_CreateTableIH(DOMTable_maxRows, DOMTable_maxCols); 120 // Force a layout by requesting the height of the table. The result is 121 // going to be ignored because there is not cleanup function registered. 122 return root_element.scrollHeight; 123 } 124 125 function DOMTableSum_Setup() { 126 // Create the table to be summed using DOM operations from JavaScript. By 127 // doing it this way the elements are all pre-wrapped. 128 DOMTable_element_count = 0; 129 var root_element = document.getElementById("benchmark_content"); 130 var table = DOMTable_CreateTable(DOMTable_maxRows, DOMTable_maxCols*5); 131 root_element.appendChild(table); 132 return root_element; 133 } 134 135 function DOMTableSum_SetupIH() { 136 // Create the table to be summed using InnerHTML. By doing it this way the 137 // elements need to be wrapped on access. 138 DOMTable_element_count = 0; 139 var root_element = document.getElementById("benchmark_content"); 140 var table = DOMTable_CreateTableIH(DOMTable_maxRows, DOMTable_maxCols*5); 141 root_element.innerHTML = table; 142 return root_element; 143 } 144 145 function DOMTableSum_ById(ignore) { 146 // Sum all elements in the table by finding each element by its id. 147 var sum = 0; 148 var maxRows = DOMTable_maxRows; 149 var maxCols = DOMTable_maxCols*5; 150 for (var r = 0; r < maxRows; r++) { 151 for (var c = 0; c < maxCols; c++) { 152 var cell = document.getElementById("$"+r+"$"+c); 153 sum += (+cell.textContent); 154 } 155 } 156 return sum; 157 } 158 159 function DOMTableSum_ByTagName(root_element) { 160 // Sum all elements in the table by getting a NodeList of all "td" elements. 161 var sum = 0; 162 var nodes = root_element.getElementsByTagName("td"); 163 var length = nodes.length; 164 for (var i = 0; i < length; i++) { 165 var cell = nodes[i]; 166 sum += (+cell.textContent); 167 } 168 return sum; 169 } 170 171 var DOMTableTest = new BenchmarkSuite('DOMTable', [ 172 new Benchmark("create", DOMTable_Create, DOMTable_CreateSetup), 173 new Benchmark("create and layout", DOMTable_CreateLayout, DOMTable_CreateSetup), 174 new Benchmark("create with innerHTML", DOMTable_InnerHTML, DOMTable_CreateSetup), 175 new Benchmark("create and layout with innerHTML", DOMTable_InnerHTMLLayout, DOMTable_CreateSetup), 176 new Benchmark("sum elements by id", DOMTableSum_ById, DOMTableSum_Setup), 177 new Benchmark("sum elements by id with innerHTML", DOMTableSum_ById, DOMTableSum_SetupIH), 178 new Benchmark("sum elements by tagname", DOMTableSum_ByTagName, DOMTableSum_Setup), 179 new Benchmark("sum elements by tagname with innerHTML", DOMTableSum_ByTagName, DOMTableSum_SetupIH) 180 ]); 181 182