New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 1239 link

Starred by 22 users

Issue metadata

Status: Fixed
Owner:
Email to this user bounced
Closed: Aug 2012
Cc:
HW: All
NextAction: ----
OS: ----
Priority: ----
Type: FeatureRequest



Sign in to add a comment

ES5 getter/setter performance

Reported by priyaj...@gmail.com, Mar 9 2011

Issue description

Owner: svenpanne@chromium.org
Status: Assigned
Labels: Type-FeatureRequest
 Issue 1693  has been merged into this issue.
Labels: HW-All
Just a small note on this issue: The performance of accessors has improved recently by a factor of 20-30, and this change has already been rolled out with dev/canary versions of Chrome (see the new numbers on jsperf.com). Now we are at least in the same ballpark as direct property access or conventional method calls, but we still need to enable inlining of accessors at their call sites. This will probably yield the remaining factor of 4-5.
Status: Fixed
Starting with v8:12328, we finally made JavaScript accessors "first-class citizens": They are handled just like normal methods now, so they can even be inlined.

Only one small restriction remains: Inlining is restricted to simple accessor uses like 'print(foo.bar)' (simple getter) or 'foo.bar = 42' (simple setter). Compound assignments (+=, -=, etc.) and increment/decrement (++/--) currently don't handle inlining for accessor properties. This is not a v8 problem in principle, we just need some refactoring to make use of the existing machinery, which will probably happen soon.


I forgot to add the numbers from the dumbgetterbenchmark.html:

Direct access: 46
__defineGetter__: 40
Old-fashioned getter: 43
ES5 getter: 40
Prototype getter: 40
Actually dumbgetterbenchmark does not allow to V8 to reveal its full potential because all test cases are done sequentially as loop on the top-level so everything goes through ICs. 

Attached benchmarks demonstrates true power of Crankshaft. If we look at the loop then getter invocation is completely inlined and hoisted out of the loop:

                  ;;; @50: load-named-field.
0x4d530e7c   188  8b7f0b         mov edi,[edi+0xb]
                  ;;; @51: gap.
0x4d530e7f   191  89fa           mov edx,edi
                  ;;; @52: tagged-to-i.
0x4d530e81   193  f6c201         test_b dl,0x1
0x4d530e84   196  0f85d1000000   jnz 411  (0x4d530f5b)
0x4d530e8a   202  d1fa           sar edx,1
                  ;;; @53: gap.
                  ;;; @54: gap.
                  ;;; @55: goto.
                  ;;; @56: label.
                  ;;; B5 - LOOP entry
                  ;;; @57: gap.
                  ;;; @58: gap.
                  ;;; @59: cmp-id-and-branch.
0x4d530e8c   204  3bc6           cmp eax,esi
0x4d530e8e   206  0f8d20000000   jnl 244  (0x4d530eb4)
                  ;;; @64: label.
                  ;;; B7
                  ;;; @65: gap.
                  ;;; @66: stack-check.
0x4d530e94   212  3b250c170209   cmp esp,[0x902170c]
0x4d530e9a   218  0f82ea000000   jc 458  (0x4d530f8a)
                  ;;; @67: gap.
                  ;;; @68: gap.
                  ;;; @69: goto.
                  ;;; @70: label.
                  ;;; B8
                  ;;; @71: gap.
0x4d530ea0   224  89cb           mov ebx,ecx
                  ;;; @72: add-i.
0x4d530ea2   226  03da           add ebx,edx
0x4d530ea4   228  0f808891ed0b   jo 0x5940a032               ;; deoptimization bailout 5
                  ;;; @73: gap.
                  ;;; @74: add-i.
0x4d530eaa   234  83c001         add eax,0x1
                  ;;; @75: gap.
                  ;;; @76: gap.
0x4d530ead   237  89d9           mov ecx,ebx
0x4d530eaf   239  8b5dd8         mov ebx,[ebp+0xd8]
                  ;;; @77: goto.
0x4d530eb2   242  ebd8           jmp 204  (0x4d530e8c)


~/src/v8 ∮ out/ia32.release/d8 notsodumbgetterbenchmark.js
*** Direct access: 595 ***
*** __defineGetter__: 595 ***
*** Old-fashioned getter: 598 ***
*** ES5 getter: 591 ***
*** Prototype getter: 598 ***

Fantastic news!
notsodumbgetterbenchmark.js
1.3 KB View Download
OK, I'll have to admit that I didn't look very closely at the code after testing revealed that Firefox 14.0.1 doesn't finish the benchmark after several minutes and we did after several seconds. ;-)

Comment 9 by cira@chromium.org, Sep 21 2012

I've recently tried to roll v8-i18n (r117:r142) to Chrome, and my change got rejected because of performance issues.

Among some notable slowdowns I've noticed that adding

Object.defineProperty(obj, 'prototype', {writable: false, enumerable: false, configurable: false})

contributed to performance loss (see http://code.google.com/p/v8-i18n/source/diff?spec=svn133&r=133&format=side&path=/trunk/src/collator.js). My test time went from 19s to 20s (300 iterations over code in question). Is that expected?

Comment 10 by m93a...@gmail.com, Sep 6 2015

It seems that Chrome is slow when dealing with configurable getter/setter properties – they are ~3 times slower than those unconfigurable. When compared to Firefox, the drop is significantly lower (~1.7 times). See: http://jsperf.com/getter-setter/100
On both Chrome 45 and on Chrome 47 canary, on that jsperf page I see

> Uncaught TypeError: Cannot read property 'name' of undefined.
>
> message: Uncaught TypeError: Cannot read property 'name' of undefined
> fileName: http://jsperf.com/benchmark-47.js
> lineNumber: 21

I have no idea what the problem is or whether it might be skewing the results.

Sign in to add a comment