perftest_numberFormat.js (5556B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 // @ts-check 5 6 var perfMetadata = { 7 owner: "Internationalization Team", 8 name: "Intl.NumberFormat", 9 description: "Test the speed of the Intl.NumberFormat implementation.", 10 options: { 11 default: { 12 perfherder: true, 13 perfherder_metrics: [ 14 { 15 name: "Intl.NumberFormat constructor iterations", 16 unit: "iterations", 17 }, 18 { name: "Intl.NumberFormat constructor accumulatedTime", unit: "ms" }, 19 { name: "Intl.NumberFormat constructor perCallTime", unit: "ms" }, 20 21 { 22 name: "Intl.NumberFormat.prototype.format iterations", 23 unit: "iterations", 24 }, 25 { 26 name: "Intl.NumberFormat.prototype.format accumulatedTime", 27 unit: "ms", 28 }, 29 { 30 name: "Intl.NumberFormat.prototype.format perCallTime", 31 unit: "ms", 32 }, 33 34 { 35 name: "Intl.NumberFormat.prototype.formatToParts iterations", 36 unit: "iterations", 37 }, 38 { 39 name: "Intl.NumberFormat.prototype.formatToParts accumulatedTime", 40 unit: "ms", 41 }, 42 { 43 name: "Intl.NumberFormat.prototype.formatToParts perCallTime", 44 unit: "ms", 45 }, 46 ], 47 verbose: true, 48 }, 49 }, 50 tags: ["intl", "ecma402"], 51 }; 52 53 add_task(function measure_numberformat() { 54 const measureConstructor = measureIterations("Intl.NumberFormat constructor"); 55 const measureFormat = measureIterations("Intl.NumberFormat.prototype.format"); 56 const measureFormatToParts = measureIterations( 57 "Intl.NumberFormat.prototype.formatToParts" 58 ); 59 60 // Re-use the config between runs. 61 62 const styles = ["decimal", "percent", "currency", "unit"]; 63 64 const numberStyles = [ 65 "arab", 66 "arabext", 67 "bali", 68 "beng", 69 "deva", 70 "fullwide", 71 "gujr", 72 "guru", 73 "hanidec", 74 "khmr", 75 "knda", 76 "laoo", 77 "latn", 78 "limb", 79 "mlym", 80 "mong", 81 "mymr", 82 "orya", 83 "tamldec", 84 "telu", 85 "thai", 86 "tibt", 87 ]; 88 89 const decimalOptions = { 90 notation: ["scientific", "engineering", "compact"], 91 useGroup: [true, false], 92 }; 93 94 const currencyOptions = { 95 currency: ["USD", "CAD", "EUR", "Yen", "MXN", "SAR", "INR", "CNY", "IDR"], 96 currencyDisplay: ["symbol", "narrowSymbol", "code", "name"], 97 currencySign: ["accounting", "standard"], 98 }; 99 100 const unitOptions = { 101 unit: [ 102 "acre", 103 "bit", 104 "byte", 105 "celsius", 106 "centimeter", 107 "day", 108 "degree", 109 "fahrenheit", 110 "fluid-ounce", 111 "foot", 112 "gallon", 113 "gigabit", 114 "gigabyte", 115 "gram", 116 "hectare", 117 "hour", 118 "inch", 119 "kilobit", 120 "kilobyte", 121 "kilogram", 122 "kilometer", 123 "liter", 124 "megabit", 125 "megabyte", 126 "meter", 127 "mile", 128 "mile-scandinavian", 129 "milliliter", 130 "millimeter", 131 "millisecond", 132 "minute", 133 "month", 134 "ounce", 135 "percent", 136 "petabyte", 137 "pound", 138 "second", 139 "stone", 140 "terabit", 141 "terabyte", 142 "week", 143 "yard", 144 "year", 145 "meter-per-second", 146 "kilometer-per-hour", 147 ], 148 unitDisplay: ["long", "short", "narrow"], 149 }; 150 151 function choose(options) { 152 return options[Math.floor(options.length * prng())]; 153 } 154 155 function randomizeConfig(config, options) { 156 for (let option in options) { 157 config[option] = choose(options[option]); 158 } 159 } 160 161 // Split each step of the benchmark into separate JS functions so that performance 162 // profiles are easy to analyze. 163 164 function benchmarkNumberFormatConstructor() { 165 for (let i = 0; i < 1000; i++) { 166 // Create a random configuration powered by a pseudo-random number generator. This 167 // way the configurations will be the same between 2 different runs. 168 const locale = pickRepresentativeLocale(); 169 const style = choose(styles); 170 const nu = choose(numberStyles); 171 let config = { 172 style, 173 nu, 174 }; 175 if (style == "decimal") { 176 randomizeConfig(config, decimalOptions); 177 } else if (style == "currency") { 178 randomizeConfig(config, currencyOptions); 179 } else if (style == "unit") { 180 randomizeConfig(config, unitOptions); 181 } 182 183 // Measure the constructor. 184 measureConstructor.start(); 185 const formatter = Intl.NumberFormat(locale, config); 186 // Also include one format operation to ensure the constructor is de-lazified. 187 formatter.format(0); 188 measureConstructor.stop(); 189 190 benchmarkFormatOperation(formatter); 191 benchmarkFormatToPartsOperation(formatter); 192 } 193 } 194 195 function benchmarkFormatOperation(formatter) { 196 // Measure the format operation. 197 for (let j = 0; j < 100; j++) { 198 let num = -1e6 + prng() * 2e6; 199 measureFormat.start(); 200 formatter.format(num); 201 measureFormat.stop(); 202 } 203 } 204 205 function benchmarkFormatToPartsOperation(formatter) { 206 // Measure the formatToParts operation. 207 for (let j = 0; j < 100; j++) { 208 let num = -1e6 + prng() * 2e6; 209 measureFormatToParts.start(); 210 formatter.formatToParts(num); 211 measureFormatToParts.stop(); 212 } 213 } 214 215 benchmarkNumberFormatConstructor(); 216 measureConstructor.reportMetrics(); 217 measureFormat.reportMetrics(); 218 measureFormatToParts.reportMetrics(); 219 220 ok(true); 221 });