perftest_dateTimeFormat.js (3745B)
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.DateTimeFormat", 9 description: "Test the speed of the Intl.DateTimeFormat implementation.", 10 options: { 11 default: { 12 perfherder: true, 13 perfherder_metrics: [ 14 { 15 name: "Intl.DateTimeFormat constructor iterations", 16 unit: "iterations", 17 }, 18 { name: "Intl.DateTimeFormat constructor accumulatedTime", unit: "ms" }, 19 { name: "Intl.DateTimeFormat constructor perCallTime", unit: "ms" }, 20 21 { 22 name: "Intl.DateTimeFormat.prototype.format iterations", 23 unit: "iterations", 24 }, 25 { 26 name: "Intl.DateTimeFormat.prototype.format accumulatedTime", 27 unit: "ms", 28 }, 29 { 30 name: "Intl.DateTimeFormat.prototype.format perCallTime", 31 unit: "ms", 32 }, 33 ], 34 verbose: true, 35 }, 36 }, 37 tags: ["intl", "ecma402"], 38 }; 39 40 add_task(function measure_date() { 41 const measureConstructor = measureIterations( 42 "Intl.DateTimeFormat constructor" 43 ); 44 const measureFormat = measureIterations( 45 "Intl.DateTimeFormat.prototype.format" 46 ); 47 48 // Re-use the config between runs. 49 50 const fieldOptions = { 51 weekday: ["narrow", "short", "long"], 52 era: ["narrow", "short", "long"], 53 year: ["2-digit", "numeric"], 54 month: ["2-digit", "numeric", "narrow", "short", "long"], 55 day: ["2-digit", "numeric"], 56 hour: ["2-digit", "numeric"], 57 minute: ["2-digit", "numeric"], 58 second: ["2-digit", "numeric"], 59 timeZoneName: ["short", "long"], 60 }; 61 62 const config = {}; 63 function randomizeConfig(name, chance) { 64 const option = fieldOptions[name]; 65 if (prng() < chance) { 66 config[name] = option[Math.floor(option.length * prng())]; 67 } else { 68 delete config[name]; 69 } 70 } 71 72 let date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738)); 73 74 // Split each step of the benchmark into separate JS functions so that performance 75 // profiles are easy to analyze. 76 77 function benchmarkDateTimeFormatConstructor() { 78 for (let i = 0; i < 1000; i++) { 79 // Create a random configuration powered by a pseudo-random number generator. This 80 // way the configurations will be the same between 2 different runs. 81 const locale = pickRepresentativeLocale(); 82 randomizeConfig("year", 0.5); 83 randomizeConfig("month", 0.5); 84 randomizeConfig("day", 0.5); 85 randomizeConfig("hour", 0.5); 86 randomizeConfig("minute", 0.5); 87 // Set the following to some lower probabilities: 88 randomizeConfig("second", 0.2); 89 randomizeConfig("timeZoneName", 0.2); 90 randomizeConfig("weekday", 0.2); 91 randomizeConfig("era", 0.1); 92 93 // Measure the constructor. 94 measureConstructor.start(); 95 const formatter = Intl.DateTimeFormat(locale, config); 96 // Also include one format operation to ensure the constructor is de-lazified. 97 formatter.format(date); 98 measureConstructor.stop(); 99 100 benchmarkFormatOperation(formatter); 101 } 102 } 103 104 const start = Date.UTC(2000); 105 const end = Date.UTC(2030); 106 const dateDiff = end - start; 107 function benchmarkFormatOperation(formatter) { 108 // Measure the format operation. 109 for (let j = 0; j < 100; j++) { 110 date = new Date(start + prng() * dateDiff); 111 measureFormat.start(); 112 formatter.format(date); 113 measureFormat.stop(); 114 } 115 } 116 117 benchmarkDateTimeFormatConstructor(); 118 measureConstructor.reportMetrics(); 119 measureFormat.reportMetrics(); 120 121 ok(true); 122 });