Arrow function invocation up to 60x slower than ES5 closure-based impl

RESOLVED WORKSFORME

Status

()

Core
JavaScript Engine
RESOLVED WORKSFORME
2 years ago
10 months ago

People

(Reporter: Kevin Decker, Unassigned)

Tracking

(Blocks: 1 bug)

38 Branch
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

2 years ago
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36

Steps to reproduce:

1. git@github.com:kpdecker/six-speed.git
2. npm install
3. gulp server
4. open http://localhost:9999/#arrow



Actual results:

Executing array functions is quite a bit slower than the lightest ES5 equivalent (function declared with closure).

See arrow sections of http://kpdecker.github.io/six-speed/


Expected results:

Performance should be similar to the ES5 implementation at worst. Ideally it would be better as as dropping arguments and forcing binding scope seem like they could provide restrictions that allow for optimizations (to the laymen)

Updated

2 years ago
Blocks: 1177735

Updated

2 years ago
Component: Untriaged → JavaScript Engine
Product: Firefox → Core

Comment 1

2 years ago
(confirming per the tracker bug)
Status: UNCONFIRMED → NEW
Ever confirmed: true
(In reply to Kevin Decker from comment #0)
> Performance should be similar to the ES5 implementation at worst. Ideally it
> would be better as as dropping arguments and forcing binding scope seem like
> they could provide restrictions that allow for optimizations (to the laymen)

A problem with our arrow functions right now is bug 889158, we unnecessarily create an arguments object on each invocation if you use |arguments| inside the arrow function (which these tests do, IIRC).
Not just unnecessarily, but *incorrectly*.  The correct way to view semantics is to imagine every function (approximately -- there are edge cases I'm not going to bother enumerating because I'd get the list wrong off the top of my head) has this at the start of it:

  var arguments = %CreateAnArgumentsObject();

Then using |arguments| just refers to that implicit variable.  But arrow functions don't have such an implied statement -- if you say |arguments|, you just see whatever |arguments| might be in enclosing scopes.  If you create an arguments object at all, semantics are observably wrong.

I really need to review the patch in that bug soon.  And, at this point, quite possibly update it to tip as penance for sin in taking so long, too.  Bah.

Comment 4

10 months ago
This is no longer an issue, http://kpdecker.github.io/six-speed/ displays "Identical" speed for arrow functions in Firefox 46 and 49. Resolving as WFM.
Status: NEW → RESOLVED
Last Resolved: 10 months ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.