Javascript Number() call is slow

RESOLVED INVALID

Status

()

Core
JavaScript Engine
--
minor
RESOLVED INVALID
7 years ago
5 years ago

People

(Reporter: mozilla, Unassigned)

Tracking

1.9.2 Branch
x86
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

7 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13

The Number() call executes much slower than I would expect, especially when passing in a value that is already a number.

Test case and test for a workaround when most values are already numbers:

function time(fn, x) {
    var t0 = new Date;
    var s;
    for(var i=0; i<2000000; i++) {
      s = fn(x);
    }
    return(new Date - t0);
}
function test(x) {
  return Number(x);
}
function test2(x) {
  if ( typeof(x) == "number" ) {
    return x;
  } else {
    return Number(x);
  }
}
time(test, 10); // 6220ms
time(test2, 10); // 1501ms
time(test, '10'); // 6770ms
time(test2, '10'); // 6994ms
time(test, null); // 5762ms
time(test2, null); // 6736ms
time(test); // 5883ms
time(test2); // 7199ms


My workaround is also significantly faster for numbers in Google Chrome 9.0.597.42 beta (50ms vs 500ms for everything else).

Reproducible: Always

Steps to Reproduce:
1. Time execution of many calls to Number(10)
2. Time execution of many calls to Number('10')
3. Time execution of many calls to Number(null)
4. Time execution of many calls to Number(undefined)
Actual Results:  
Number(10) is the slowest.
All results are rather slow.

Expected Results:  
Number(10) is as fast as Number(null) and Number(undefined).
All results are faster.
Please retest with Firefox4beta8 or later
Assignee: nobody → general
Component: General → JavaScript Engine
Product: Firefox → Core
QA Contact: general → general
Version: unspecified → 1.9.2 Branch
Number(N) has to allocate a new object, which is of course way more expensive than not having to allocate a new object.

That said, I'm a little confused by the numbers you cite.  I ran your test in Firefox 3.6, and I see these numbers (in ms):

68
26
226
294
83
177
84
115

So while the general pattern is similar to what you observe (and has to do with the fact that Number() is an inherently expensive operation), the actual times are somewhere around 100x faster than yours.  I have a hard time believing my processor (a 2.66GHz core i7) is 100x faster than yours.  So why are you seeing the numbers you're seeing?  Is this a clean profile?

Oh, and of course for me in 3.6 Number(10) is in fact faster than Number(null) or Number(undefined).  All of these are faster than Number('10'), which has a string-to-number conversion it has to do.  Those aren't cheap either.

As far as comparisons to Chrome, btw, running a current v8 (trunk; so what will ship in Chrome 11, most likely) on the test above gives me these numbers:

51
20
52
53
58
60
58
59

Running a current Gecko js shell (which is what will ship in Firefox 4) gives me:

35
35
137
165
53
78
51
74

The string-to-number conversion is a known pain point; the rest of the results are somewhat similar, and there's certainly not 10x variance visible anywhere in the v8 results.
(Reporter)

Comment 3

7 years ago
Tracked down the major part of the issue... it was actually Firebug slowing things down so much (forgot it was even enabled). This makes it much less of an issue.

Re-ran the test on FF3.6 on Windows 7 without Firebug enabled, and got much better numbers.... but I'm still seeing Number(10) as being slower than Number(null).
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12

151
83
491
545
131
215
137
217


I also ran some others for more comparison...

function test3(x) {
 return String(x);
}
function test4(x) {
 return Boolean(x);
}
time(test3, '10')
time(test3, 10)
time(test4, 0)
time(test4, 1)
time(test4, true)

Times for those:
22
77
121
121
109


In order of actual execution speed, from slowest to fastest, I would expect...
new String, new Number, and new Boolean
Number('10')
String(10)
String('10'), String(null), String(undefined)
Number(10), Number(null), Number(undefined)
Boolean(anything)
Ah, yeah.  Measuring performance with debugging hooks enabled _and_ the jit turned off is pretty meaningless.

I have no idea why you're seeing Number(10) being slower than Number(null); it may have to do with exactly when garbage collections happen to occur in your setup (since if a gc happens during one of the tests but not another it will skew the results).  The precise locations of garbage collections have been known to differ by OS (as well as various other things that affect memory layout).
Please reopen if this is still slow with IonMonkey.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.