Closed Bug 1514851 Opened 6 years ago Closed 3 months ago

Number.prototype.toLocaleString is slow

Categories

(Core :: JavaScript: Internationalization API, defect, P2)

defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: jorendorff, Unassigned)

Details

Attachments

(2 files)

function test(n) { let t0 = Date.now(); for (let i = 0; i < n; i++) { someGlobalVar = i.toLocaleString('foo'); } return Date.now() - t0; } On my macbook, test(30000) returns about 1000, i.e. it takes about a second to run. Maybe it's just me, but that seems slow; we can do about ten million calls to i.toString() in the same amount of time. Is there work in toLocaleString that we should be caching?
It's still slow if you use 'en-US' as the locale string.
One reason to care about this is that Array.prototype.toLocaleString() does in fact call .toLocaleString on each element, so it might be an almost normal thing to have this method called thousands of times.
This has real-world consequences: toLocaleString is so slow that using it in about:memory caused serious performance problems (bug 1517354) that were resolved by ripping it out.

bug 15173540

There's a typo in that bug number, it should be bug 1517354.

Attached file test.html
Attached image Profile

https://perfht.ml/31GU6ci

Looks like 77% of this is in js::intl_FormatNumber unsurprisingly. (And a further 7% in one of the other leaves, not sure why precisely.) Within there,

  • 27% in unum_open
  • 19% in PartitionNumberFormat and most of that in unum_formatDoubleForFields
  • 18% in js::intl::GetInternalsObject
  • 12% in unum_setAttribute (!) corresponding to icu::DecimalFormat::setRoundingMode (wat)

Some portions of overhead in there that we could eliminate for sure. Other bits in there are in ICU. We aren't entirely helped by jumping in and out of self-hosted code frequently, it appears, perhaps as a general concern.

A fair number of things that could be investigated here, for sure.

Type: enhancement → defect
Priority: -- → P2
Severity: normal → S3

Not sure what would be a reasonable value here, but my experimentation suggests this is good enough

Here's a profile of Jason's test case in the shell run with 300,000 iterations:

https://share.firefox.dev/4cd0JH0

icu_73::(anonymous namespace)::DecFmtSymDataSink::put is the highest consumer of time now, and that's only 2.5%

Status: NEW → RESOLVED
Closed: 3 months ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: