Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
// @ts-check
var perfMetadata = {
owner: "Internationalization Team",
name: "Intl.NumberFormat",
description: "Test the speed of the Intl.NumberFormat implementation.",
options: {
default: {
perfherder: true,
perfherder_metrics: [
{
name: "Intl.NumberFormat constructor iterations",
unit: "iterations",
},
{ name: "Intl.NumberFormat constructor accumulatedTime", unit: "ms" },
{ name: "Intl.NumberFormat constructor perCallTime", unit: "ms" },
{
name: "Intl.NumberFormat.prototype.format iterations",
unit: "iterations",
},
{
name: "Intl.NumberFormat.prototype.format accumulatedTime",
unit: "ms",
},
{
name: "Intl.NumberFormat.prototype.format perCallTime",
unit: "ms",
},
{
name: "Intl.NumberFormat.prototype.formatToParts iterations",
unit: "iterations",
},
{
name: "Intl.NumberFormat.prototype.formatToParts accumulatedTime",
unit: "ms",
},
{
name: "Intl.NumberFormat.prototype.formatToParts perCallTime",
unit: "ms",
},
],
verbose: true,
},
},
tags: ["intl", "ecma402"],
};
add_task(function measure_numberformat() {
const measureConstructor = measureIterations("Intl.NumberFormat constructor");
const measureFormat = measureIterations("Intl.NumberFormat.prototype.format");
const measureFormatToParts = measureIterations(
"Intl.NumberFormat.prototype.formatToParts"
);
// Re-use the config between runs.
const styles = ["decimal", "percent", "currency", "unit"];
const numberStyles = [
"arab",
"arabext",
"bali",
"beng",
"deva",
"fullwide",
"gujr",
"guru",
"hanidec",
"khmr",
"knda",
"laoo",
"latn",
"limb",
"mlym",
"mong",
"mymr",
"orya",
"tamldec",
"telu",
"thai",
"tibt",
];
const decimalOptions = {
notation: ["scientific", "engineering", "compact"],
useGroup: [true, false],
};
const currencyOptions = {
currency: ["USD", "CAD", "EUR", "Yen", "MXN", "SAR", "INR", "CNY", "IDR"],
currencyDisplay: ["symbol", "narrowSymbol", "code", "name"],
currencySign: ["accounting", "standard"],
};
const unitOptions = {
unit: [
"acre",
"bit",
"byte",
"celsius",
"centimeter",
"day",
"degree",
"fahrenheit",
"fluid-ounce",
"foot",
"gallon",
"gigabit",
"gigabyte",
"gram",
"hectare",
"hour",
"inch",
"kilobit",
"kilobyte",
"kilogram",
"kilometer",
"liter",
"megabit",
"megabyte",
"meter",
"mile",
"mile-scandinavian",
"milliliter",
"millimeter",
"millisecond",
"minute",
"month",
"ounce",
"percent",
"petabyte",
"pound",
"second",
"stone",
"terabit",
"terabyte",
"week",
"yard",
"year",
"meter-per-second",
"kilometer-per-hour",
],
unitDisplay: ["long", "short", "narrow"],
};
function choose(options) {
return options[Math.floor(options.length * prng())];
}
function randomizeConfig(config, options) {
for (let option in options) {
config[option] = choose(options[option]);
}
}
// Split each step of the benchmark into separate JS functions so that performance
// profiles are easy to analyze.
function benchmarkNumberFormatConstructor() {
for (let i = 0; i < 1000; i++) {
// Create a random configuration powered by a pseudo-random number generator. This
// way the configurations will be the same between 2 different runs.
const locale = pickRepresentativeLocale();
const style = choose(styles);
const nu = choose(numberStyles);
let config = {
style,
nu,
};
if (style == "decimal") {
randomizeConfig(config, decimalOptions);
} else if (style == "currency") {
randomizeConfig(config, currencyOptions);
} else if (style == "unit") {
randomizeConfig(config, unitOptions);
}
// Measure the constructor.
measureConstructor.start();
const formatter = Intl.NumberFormat(locale, config);
// Also include one format operation to ensure the constructor is de-lazified.
formatter.format(0);
measureConstructor.stop();
benchmarkFormatOperation(formatter);
benchmarkFormatToPartsOperation(formatter);
}
}
function benchmarkFormatOperation(formatter) {
// Measure the format operation.
for (let j = 0; j < 100; j++) {
let num = -1e6 + prng() * 2e6;
measureFormat.start();
formatter.format(num);
measureFormat.stop();
}
}
function benchmarkFormatToPartsOperation(formatter) {
// Measure the formatToParts operation.
for (let j = 0; j < 100; j++) {
let num = -1e6 + prng() * 2e6;
measureFormatToParts.start();
formatter.formatToParts(num);
measureFormatToParts.stop();
}
}
benchmarkNumberFormatConstructor();
measureConstructor.reportMetrics();
measureFormat.reportMetrics();
measureFormatToParts.reportMetrics();
ok(true);
});