Sei sulla pagina 1di 40

High-Speed ES2015

Benedikt Meurer
Google Munich
@bmeurer

Proprietary Proprietary
An Engines View...

Proprietary
ES2015 is cool!!!!1

Proprietary
hug
ES2015 is a
monster e
Proprietary
Maps Proxies
Promise
Classes
s
Spread
Tagged Sets TypedArray
Template s
Strings

ES2015
Lexical
Scoping
Well-
known Computed
Symbols Iteratio Property
Generato
n Names
rs
Array
Builtins Modules
Arrow
Functions

Proprietary
2.2
x

258 566
pages pages

Proprietary
Performance
Measurement

Proprietary
Old vs. New

Proprietary
Proprietary
Six-speed methodology
Based on github.com/kpdecker/six-speed by @kpdecker

Measure naive ES5 and recommended ES2015 (Micro-benchmarks!)

Short-term goal: Slowdown below 2x for all (interesting) features

Long-term goal: ES2015 on-par or faster

Proprietary
Six-speed methodology (Example)
for-of-array.es5 for-of-array.es6

var data = [1,2,3]; var data = [1,2,3];

function fn() { function fn() {


var ret = ''; var ret = '';
for (var i = 0; i < data.length; i++) { for (var value of data) {
ret += data[i]; ret += value;
} }
return ret; return ret;
} }

assertEqual(fn(), '123'); assertEqual(fn(), '123');

test(fn); test(fn);

Proprietary
Proprietary
How to get
involved?
Contribute to ES2015 and
beyond performance plan:
goo.gl/CNSM83

Contribute to Six-Speed:
fhinkel.github.io/six-speed

Ideas for real ES2015


performance test suite
We want you to help
us! Proprietary
Destructuring

Proprietary
Destructuring

function foo6(a) { function foo5(a) {


const [x] = a; var x = a[0];
return x; return x;
} }

$ d8 --turbo --print-bytecode destructuring.js


Proprietary
Destructuring the ES5 way
0 : StackCheck
function foo5(a) { 1
2
:
:
LdaZero
LdaKeyedProperty a0, [2]
a[0]
var x = a[0]; 5
7
:
:
Star r0
Nop

return x; 8 : Return

Proprietary
Destructuring the ES2015 way
0 : LdaTheHole
function foo6(a) { 1 : Star r6
3 : StackCheck
const [x] = a; 4 : Mov a0, r0
7 : LdaNamedProperty r0, [0], [2]

return x; 11 : Star r11


13 : CallProperty r11, r0-r0, [4]
...
} 49 : LdaNamedProperty r1, [1], [8]
53 : Star r14
55 : CallProperty r14, r1-r1, [6]
60 : Star r3
...
74 : LdaNamedProperty r3, [2], [10]
78 : JumpIfToBooleanFalse @ 85
...
85 : LdaNamedProperty r3, [3], [12]
...
284 : Return

Holy Smokes! Proprietary


Destructuring the ES2015 way lets see!
1. Let iterator be a[Symbol.iterator]() 0 : LdaTheHole
1 : Star r6 @@iterato
3 : StackCheck
2. Let result be iterator.next() 4 : Mov a0, r0 r
7 : LdaNamedProperty r0, [0], [2]
3. Let x be undefined 11 : Star r11
13 : CallProperty r11, r0-r0, [4] next
...
4. If ToBoolean(result.done) yields true, goto to 49 : LdaNamedProperty r1, [1], [8]
step 6 53 : Star r14
55 : CallProperty r14, r1-r1, [6]
60 : Star r3
5. Assign result.value to x
Caution: Oversimplified! ...
done
74 : LdaNamedProperty r3, [2], [10]
6.Ignores
Return x 78 : JumpIfToBooleanFalse @ 85
...
85 : LdaNamedProperty r3, [3], [12] value
Exception handling ...
284 : Return

Iterator closing

Proprietary
Can I haz fast plz?

Proprietary
Destructuring the ES2015 way lets see!
1. Let iterator be a[Symbol.iterator]()
Depends on
2. Let result be iterator.next() a

3. Let x be undefined Usually no-


op
4. If ToBoolean(result.done) yields true, goto to
step 6

5. Assign result.value to x

6. Return x
Lets consider for
example
foo6([0]);

Proprietary
Destructuring the ES2015 way Array
destructuring
1. Let iterator be a[Symbol.iterator]() Array.prototype[@@iterator]

2. Let result be iterator.next() %ArrayIteratorPrototype%.next

3. Let x be undefined

4. If ToBoolean(result.done) yields true, goto to


step 6

5. Assign result.value to x

6. Return x
Lets consider for
example
foo6([0]);

Proprietary
Destructuring the ES2015 way Array
destructuring
1. Let iterator be CreateArrayIterator(a,value)

2. Let result be %ArrayIteratorPrototype%.next(iterator)

3. Let x be undefined

4. If ToBoolean(result.done) yields true, goto to step 6

5. Assign result.value to x
Local
6. Return xallocations

a.length

a[index]

Proprietary
Destructuring the ES2015 way Array
destructuring
a.length and a[index] already optimizable
TurboFan Load Elimination and Escape Analysis to
eliminate non-escaping allocations
Plus some magic to kill the remaining overhead
(exception handling, iterator closing, etc.)
Only ~1.2x slower now in
Node 8
(Source: fhinkel.github.io/six-speed)
Proprietary
Spread calls and
Rest parameters

Proprietary
Spread calls and Rest parameters simple case
ES5:

Math.max.apply(Math,
[1,2,3]);

ES2015:

Math.max(...[1,2,3]);

From 19x slower (Node 7) to 1.5x slower


(Node 8)!
Proprietary
Spread calls and Rest parameters interesting
case 0 : CreateRestParameter
function max0(...args) { 1 : Star r0
return Math.max(0,...args); 3 : StackCheck
4 : LdaUndefined
} ...args
5 : Star r2
7 : LdaGlobal [0], [2]
10 : Star r1
Math 12 : LdaNamedProperty r1, [1], [4]
16 : Star r3
Four temporary
Arrays!
Math.max 18 : LdaUndefined
to the
[0]
19 : Star r6
ec o de
by t
21 : CreateArrayLiteral [2], [0], #9
e d
25 : Star r7
at u e:
d ic s c
27 : LdaUndefined
re
args = %SpreadIterable(...args) De 28 : Star r9
30 : Mov r0, r10
S pread
ll W ith
33 : CallJSRuntime [154], r9-r10

Ca
37 : Star r8
args = %SpreadArguments([0], args) 39 : CallJSRuntime [153], r6-r8
43 : Star r5
45 : Mov r1, r4
return %Apply(Math.max, Math, args) 48 : CallJSRuntime [149], r2-r5
52 : Return
Proprietary
Spread calls and Rest parameters interesting
case 0 : CreateRestParameter
function max0(...args) { 1 : Star r0
return Math.max(0,...args); 3 : StackCheck
4 : LdaUndefined
} 5 : Star r2
7 : LdaGlobal [0], [2]
10 : Star r1
12 : LdaNamedProperty r1, [1], [4]
CallWithSpread(Math.max, Math, 0, args) 16 : Star r3
17 : LdaZero
18 : Star r2
19 : CallWithSpread r3, r1, r2-r2, r0
24 : Return

target receive spread


r explicit
parameter
Work-in-progress, not for
s

Node 8 Proprietary
Accidents

Proprietary
Proprietary
Proprietary
Disabled fast-path for
instanceof!

Proprietary
@@hasInstance vs instanceof
@@hasInstance made instanceof monkey-patchable

Global guard to retain instanceof fast-path


Install Symbol.hasInstance property anywhere disables fast-path globally for the VM

Further instanceof take slow-path

slow
fast

Proprietary
@@hasInstance vs instanceof
Avoid global protector

Fast-path for o instanceof Foo


Foo is (known) constructor

Foo[Symbol.hasInstance] during optimized compilation

Proprietary
Proprietary
Approaching ES2017

Proprietary
Proprietary
Proprietary
Meaningful async/await
Performance test?

Proprietary
Proprietary
Questions?
Feedback!

Proprietary

Potrebbero piacerti anche