Know Your Engines How to Make Your JavaScript Fast Dave Mandelin 8 - - PowerPoint PPT Presentation

know your engines
SMART_READER_LITE
LIVE PREVIEW

Know Your Engines How to Make Your JavaScript Fast Dave Mandelin 8 - - PowerPoint PPT Presentation

Know Your Engines How to Make Your JavaScript Fast Dave Mandelin 8 November 2011 OReilly Velocity Europe Tuesday, November 8, 2011 JavaScript is getting really fast and programs are getting crazy Bullet physics engine (ammo.js) H.264


slide-1
SLIDE 1

Know Your Engines

How to Make Your JavaScript Fast Dave Mandelin 8 November 2011 O’Reilly Velocity Europe

Tuesday, November 8, 2011

slide-2
SLIDE 2

JavaScript is getting really fast and programs are getting crazy

Bullet physics engine (ammo.js) H.264 decoder at 30 fps (broadway.js)

Tuesday, November 8, 2011

slide-3
SLIDE 3

But it’s still easy to go slow

function f() { var sum = 0; for (var i = 0; i < N; ++i) { sum += i; } } function f() { eval(“”); var sum = 0; for (var i = 0; i < N; ++i) { sum += i; } }

Tuesday, November 8, 2011

slide-4
SLIDE 4

But it’s still easy to go slow

function f() { var sum = 0; for (var i = 0; i < N; ++i) { sum += i; } } function f() { eval(“”); var sum = 0; for (var i = 0; i < N; ++i) { sum += i; } }

20 40 60 80 without eval with eval

with eval(“”) up to 10x slower!

Tuesday, November 8, 2011

slide-5
SLIDE 5

Making JavaScript Fast

How JITs make JavaScript not slow How not to ruin animation with pauses How to write JavaScript that’s not slow

Or, Not Making JavaScript Slow

Tuesday, November 8, 2011

slide-6
SLIDE 6

The 2006 JavaScript Engine

Tuesday, November 8, 2011

slide-7
SLIDE 7

Inside the 2006 JS Engine

Front End Interpreter DOM Standard Library Garbage Collector

Tuesday, November 8, 2011

slide-8
SLIDE 8

Inside the 2006 JS Engine

Front End

// JavaScript source e.innerHTML = n + “ items”;

Interpreter DOM Standard Library Garbage Collector

Tuesday, November 8, 2011

slide-9
SLIDE 9

Inside the 2006 JS Engine

Front End

// JavaScript source e.innerHTML = n + “ items”; // bytecode (AST in some engines) tmp_0 = add var_1 str_3 setprop var_0 ‘innerHTML’ tmp_0

Interpreter DOM Standard Library Garbage Collector

Tuesday, November 8, 2011

slide-10
SLIDE 10

Inside the 2006 JS Engine

Front End

// JavaScript source e.innerHTML = n + “ items”; // bytecode (AST in some engines) tmp_0 = add var_1 str_3 setprop var_0 ‘innerHTML’ tmp_0

Interpreter DOM Standard Library Garbage Collector

Run the bytecode

Tuesday, November 8, 2011

slide-11
SLIDE 11

Inside the 2006 JS Engine

Front End

// JavaScript source e.innerHTML = n + “ items”; // bytecode (AST in some engines) tmp_0 = add var_1 str_3 setprop var_0 ‘innerHTML’ tmp_0

Interpreter DOM Standard Library Garbage Collector

Run the bytecode Reclaim memory

Tuesday, November 8, 2011

slide-12
SLIDE 12

Inside the 2006 JS Engine

Front End

// JavaScript source e.innerHTML = n + “ items”; // bytecode (AST in some engines) tmp_0 = add var_1 str_3 setprop var_0 ‘innerHTML’ tmp_0

Interpreter DOM Standard Library Garbage Collector

Run the bytecode Set innerHTML Reclaim memory

Tuesday, November 8, 2011

slide-13
SLIDE 13

Why it’s hard to make JS fast

Because JavaScript is an untyped language. untyped = no type declarations

Tuesday, November 8, 2011

slide-14
SLIDE 14

Operations in an untyped language

  • if y and z are numbers, numeric addition
  • if y and z are strings, concatenation
  • and many other cases; y and z can have different types

x = y + z can mean many things

Tuesday, November 8, 2011

slide-15
SLIDE 15

Engine-Internal Types

JS engines use finer-grained types internally.

number

JavaScript type

  • bject

Tuesday, November 8, 2011

slide-16
SLIDE 16

Engine-Internal Types

JS engines use finer-grained types internally.

number 32-bit* integer 64-bit floating-point

JavaScript type Engine type

  • bject

Tuesday, November 8, 2011

slide-17
SLIDE 17

Engine-Internal Types

JS engines use finer-grained types internally.

number 32-bit* integer 64-bit floating-point

JavaScript type Engine type

  • bject

{ a: 1 } { a: 1, b: 2 } { a: get ... } { a: 1, __proto__ = new C }

Tuesday, November 8, 2011

slide-18
SLIDE 18

Engine-Internal Types

JS engines use finer-grained types internally.

number 32-bit* integer 64-bit floating-point

JavaScript type Engine type

  • bject

{ a: 1 } { a: 1, b: 2 } { a: get ... } { a: 1, __proto__ = new C } Different shapes

Tuesday, November 8, 2011

slide-19
SLIDE 19

Values in an untyped language

Boxed Unboxed Purpose Storage Computation Examples

(INT, 55) 55 (STRING, “foo”) “foo”

Definition

(type tag, C++ value) C++ value

Because JavaScript is untyped, the interpreter needs boxed values.

  • nly boxed values can be stored in variables,
  • nly unboxed values can be computed with (+, *, etc)

Tuesday, November 8, 2011

slide-20
SLIDE 20

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

Tuesday, November 8, 2011

slide-21
SLIDE 21

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory

Tuesday, November 8, 2011

slide-22
SLIDE 22

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory

Tuesday, November 8, 2011

slide-23
SLIDE 23

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action

Tuesday, November 8, 2011

slide-24
SLIDE 24

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z

Tuesday, November 8, 2011

slide-25
SLIDE 25

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action

Tuesday, November 8, 2011

slide-26
SLIDE 26

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x

Tuesday, November 8, 2011

slide-27
SLIDE 27

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the boxed output x to memory

Tuesday, November 8, 2011

slide-28
SLIDE 28

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the boxed output x to memory

This is the only real work!

Tuesday, November 8, 2011

slide-29
SLIDE 29

Running Code in the Interpreter

Here’s what the interpreter must do to execute x = y + z:

  • read the operation x = y + z from memory
  • read the boxed inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the boxed output x to memory

This is the only real work! Everything else is

  • verhead.

Tuesday, November 8, 2011

slide-30
SLIDE 30

The 2011 JavaScript Engine

Tuesday, November 8, 2011

slide-31
SLIDE 31

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Tuesday, November 8, 2011

slide-32
SLIDE 32

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Untyped Compiler

Compile to x86/x64/ARM

Tuesday, November 8, 2011

slide-33
SLIDE 33

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Untyped Compiler

Compile to x86/x64/ARM

CPU

Fast!

x86/x64/ARM

Tuesday, November 8, 2011

slide-34
SLIDE 34

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Untyped Compiler Typed Compiler

Compile to x86/x64/ARM

CPU

Fast! Ultra Fast!

x86/x64/ARM

Tuesday, November 8, 2011

slide-35
SLIDE 35

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Untyped Compiler Typed Compiler

Compile to x86/x64/ARM

CPU

Fast! Ultra Fast!

x86/x64/ARM

Tuesday, November 8, 2011

slide-36
SLIDE 36

Inside the 2011 JS Engine

Front End

JavaScript source bytecode/AST

Interpreter DOM

Standard Library Garbage Collector

Untyped Compiler Typed Compiler

Compile to x86/x64/ARM

CPU

Fast! THE SLOW ZONE Ultra Fast!

x86/x64/ARM

Tuesday, November 8, 2011

slide-37
SLIDE 37

Running Code with the JIT

The basic JIT compiler on x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

All Major Browsers

Tuesday, November 8, 2011

slide-38
SLIDE 38

Running Code with the JIT

The basic JIT compiler on x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

All Major Browsers

CPU does it for us!

Tuesday, November 8, 2011

slide-39
SLIDE 39

Running Code with the JIT

The basic JIT compiler on x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

All Major Browsers

CPU does it for us! JIT code can keep things in registers

Tuesday, November 8, 2011

slide-40
SLIDE 40

Choosing the action in the JIT

Tuesday, November 8, 2011

slide-41
SLIDE 41

Choosing the action in the JIT

  • Many cases for operators like +

Tuesday, November 8, 2011

slide-42
SLIDE 42

Choosing the action in the JIT

  • Many cases for operators like +
  • Engines generate fast JIT code for “common cases”
  • number + number
  • string + string

Tuesday, November 8, 2011

slide-43
SLIDE 43

Choosing the action in the JIT

  • Many cases for operators like +
  • Engines generate fast JIT code for “common cases”
  • number + number
  • string + string
  • “Rare cases” run in the slow zone
  • number + undefined

Tuesday, November 8, 2011

slide-44
SLIDE 44

JITs for Regular Expressions

  • There is a separate JIT for regular expressions
  • Regular expressions are generally faster than manual search
  • Still in the slow zone:
  • Some complex regexes (example: backreferences)
  • Building result arrays (test much faster than exec)

All Major Browsers

Tuesday, November 8, 2011

slide-45
SLIDE 45

Object Properties

function f(obj) { return obj.a + 1; }

Tuesday, November 8, 2011

slide-46
SLIDE 46

Object Properties

  • Need to search obj for a property named a slow

function f(obj) { return obj.a + 1; }

Tuesday, November 8, 2011

slide-47
SLIDE 47

Object Properties

  • Need to search obj for a property named a slow
  • May need to search prototype chain up several levels super-slow

function f(obj) { return obj.a + 1; }

Tuesday, November 8, 2011

slide-48
SLIDE 48

Object Properties

  • Need to search obj for a property named a slow
  • May need to search prototype chain up several levels super-slow
  • Finally, once we’ve found it, get the property value fast!

function f(obj) { return obj.a + 1; }

Tuesday, November 8, 2011

slide-49
SLIDE 49

ICs: a mini-JIT for objects

All Major Browsers

Tuesday, November 8, 2011

slide-50
SLIDE 50

ICs: a mini-JIT for objects

  • Properties become fast with inline caching (we prefer IC)

All Major Browsers

Tuesday, November 8, 2011

slide-51
SLIDE 51

ICs: a mini-JIT for objects

  • Properties become fast with inline caching (we prefer IC)
  • Basic plan:

All Major Browsers

Tuesday, November 8, 2011

slide-52
SLIDE 52

ICs: a mini-JIT for objects

  • Properties become fast with inline caching (we prefer IC)
  • Basic plan:
  • 1. First time around, search for the property in the Slow Zone

All Major Browsers

Tuesday, November 8, 2011

slide-53
SLIDE 53

ICs: a mini-JIT for objects

  • Properties become fast with inline caching (we prefer IC)
  • Basic plan:
  • 1. First time around, search for the property in the Slow Zone
  • 2. But record the steps done to actually get the property

All Major Browsers

Tuesday, November 8, 2011

slide-54
SLIDE 54

ICs: a mini-JIT for objects

  • Properties become fast with inline caching (we prefer IC)
  • Basic plan:
  • 1. First time around, search for the property in the Slow Zone
  • 2. But record the steps done to actually get the property
  • 3. Then JIT a little piece of code that does just those steps

All Major Browsers

Tuesday, November 8, 2011

slide-55
SLIDE 55

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code

Tuesday, November 8, 2011

slide-56
SLIDE 56

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1

Tuesday, November 8, 2011

slide-57
SLIDE 57

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 shape=12, in position 1

Tuesday, November 8, 2011

slide-58
SLIDE 58

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 shape=12, in position 1

Tuesday, November 8, 2011

slide-59
SLIDE 59

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 shape=12, in position 1

Tuesday, November 8, 2011

slide-60
SLIDE 60

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 shape=12, in position 1

Tuesday, November 8, 2011

slide-61
SLIDE 61

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 shape=12, in position 1 shape=15, in position 0

Tuesday, November 8, 2011

slide-62
SLIDE 62

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 icStub_2: compare obj.shape, 15 jumpIfFalse slowPropAccess load obj.props[0] jump continue_1 shape=12, in position 1 shape=15, in position 0

Tuesday, November 8, 2011

slide-63
SLIDE 63

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 icStub_2: compare obj.shape, 15 jumpIfFalse slowPropAccess load obj.props[0] jump continue_1 shape=12, in position 1 shape=15, in position 0

Tuesday, November 8, 2011

slide-64
SLIDE 64

ICs: Example

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) { return obj.b + 1; }

Example Code Generated JIT Code

... jump slowPropAccess continue_1: ... slowPropAccess: ... set up call call ICGetProp ; C++ Slow Zone jump continue_1 icStub_1: compare obj.shape, 12 jumpIfFalse slowPropAccess load obj.props[1] jump continue_1 icStub_2: compare obj.shape, 15 jumpIfFalse slowPropAccess load obj.props[0] jump continue_1 shape=12, in position 1 shape=15, in position 0

Tuesday, November 8, 2011

slide-65
SLIDE 65

These are fast because of ICs

var q = 4; var r; function f(obj) { r = q; }

Global Variable Access

Tuesday, November 8, 2011

slide-66
SLIDE 66

These are fast because of ICs

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) {

  • bj2.b = obj1.c;

}

Direct Property Access

var q = 4; var r; function f(obj) { r = q; }

Global Variable Access

Tuesday, November 8, 2011

slide-67
SLIDE 67

These are fast because of ICs

var obj1 = { a: 1, b: 2, c: 3 }; var obj2 = { b: 2 }; function f(obj) {

  • bj2.b = obj1.c;

}

Direct Property Access

var q = 4; var r; function f(obj) { r = q; }

Global Variable Access

var f = function() { var x = 1; var g = function() { var sum = 0; for (var i = 0; i < N; ++i) { sum += x; } return sum; } return g(); }

Closure Variable Access

Tuesday, November 8, 2011

slide-68
SLIDE 68

Prototype chains don’t hurt

function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B;

Tuesday, November 8, 2011

slide-69
SLIDE 69

Prototype chains don’t hurt

new C(1) new B new A function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B; proto

Tuesday, November 8, 2011

slide-70
SLIDE 70

Prototype chains don’t hurt

new C(1) new B new A function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B; new C(2) proto

Tuesday, November 8, 2011

slide-71
SLIDE 71

Prototype chains don’t hurt

new C(1) new B new A function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B; new C(2) new C(3) proto

Tuesday, November 8, 2011

slide-72
SLIDE 72

Prototype chains don’t hurt

new C(1) new B new A function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B; new C(2) new C(3)

Shape of new C objects determines prototype

proto

Tuesday, November 8, 2011

slide-73
SLIDE 73

Prototype chains don’t hurt

new C(1) new B new A function A(x) { this.x = x; } function B(y) { this.y = y; } B.prototype = new A; function C(z) { this.z = z; } C.prototype = new B; new C(2) new C(3)

Shape of new C objects determines prototype

  • > IC can generate code that checks shape,

then reads directly from prototype without walking

proto

Tuesday, November 8, 2011

slide-74
SLIDE 74

Many Shapes Slow Down ICs

function f(obj) { return obj.p; }

What happens if many shapes of obj are passed to f? ICs end up looking like this:

Tuesday, November 8, 2011

slide-75
SLIDE 75

Many Shapes Slow Down ICs

function f(obj) { return obj.p; }

What happens if many shapes of obj are passed to f? ICs end up looking like this:

jumpIf shape != 12 read for shape 12

Tuesday, November 8, 2011

slide-76
SLIDE 76

Many Shapes Slow Down ICs

function f(obj) { return obj.p; }

What happens if many shapes of obj are passed to f? ICs end up looking like this:

jumpIf shape != 12 read for shape 12 jumpIf shape != 15 read for shape 15

Tuesday, November 8, 2011

slide-77
SLIDE 77

Many Shapes Slow Down ICs

function f(obj) { return obj.p; }

What happens if many shapes of obj are passed to f? ICs end up looking like this:

jumpIf shape != 12 read for shape 12 jumpIf shape != 15 read for shape 15 jumpIf shape != 6 read for shape 6

Tuesday, November 8, 2011

slide-78
SLIDE 78

Many Shapes Slow Down ICs

function f(obj) { return obj.p; }

What happens if many shapes of obj are passed to f? ICs end up looking like this:

jumpIf shape != 12 read for shape 12 jumpIf shape != 15 read for shape 15 jumpIf shape != 6 read for shape 6 jumpIf shape != 16 read for shape 16 jumpIf shape != 22 read for shape 22 jumpIf shape != 3 read for shape 3 ...

Tuesday, November 8, 2011

slide-79
SLIDE 79

Many shapes in practice

25 50 75 100 1 2 8 16 32 100 200 nanoseconds/iteration # of shapes at property read site

IE Opera Chrome Firefox Safari

IE Slow Zone for 2+ shapes Opera # of shapes doesn’t matter! Chrome more shapes -> slower Firefox slower with more shapes, Safari but levels off in Slow Zone

Tuesday, November 8, 2011

slide-80
SLIDE 80

Deeply Nested Closures are Slower

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y;

Tuesday, November 8, 2011

slide-81
SLIDE 81

Deeply Nested Closures are Slower

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y; j call object f call object h call object First call to f

Tuesday, November 8, 2011

slide-82
SLIDE 82

Deeply Nested Closures are Slower

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y; j call object f call object f call object j call object h call object h call object First call to f Second call to f

Tuesday, November 8, 2011

slide-83
SLIDE 83

Deeply Nested Closures are Slower

  • Prototype chains don’t slow us down, but deep closure nesting does. Why?

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y; j call object f call object f call object j call object h call object h call object First call to f Second call to f

Tuesday, November 8, 2011

slide-84
SLIDE 84

Deeply Nested Closures are Slower

  • Prototype chains don’t slow us down, but deep closure nesting does. Why?
  • Every call to f generates a unique closure object to hold x.

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y; j call object f call object f call object j call object h call object h call object First call to f Second call to f

Tuesday, November 8, 2011

slide-85
SLIDE 85

Deeply Nested Closures are Slower

  • Prototype chains don’t slow us down, but deep closure nesting does. Why?
  • Every call to f generates a unique closure object to hold x.
  • The engine must walk to find the right x each time

var f = function() { var x; var g = function() { var h = function() { var y; var i = function () { var j = function() { z = x + y; j call object f call object f call object j call object h call object h call object First call to f Second call to f

Tuesday, November 8, 2011

slide-86
SLIDE 86

Properties in the Slow Zone

Tuesday, November 8, 2011

slide-87
SLIDE 87

Properties in the Slow Zone

var a = {}; a.x;

Undefined Property

(Fast on Firefox, Chrome)

Tuesday, November 8, 2011

slide-88
SLIDE 88

Properties in the Slow Zone

var a = {}; a.x;

Undefined Property

(Fast on Firefox, Chrome) var a = document.getByElementId(“foo”); a.id;

DOM Access

(I only tested .id, so take with a grain of salt--

  • ther properties may differ)

Tuesday, November 8, 2011

slide-89
SLIDE 89

Properties in the Slow Zone

var a = {}; a.x;

Undefined Property

(Fast on Firefox, Chrome) var a = { x: get() { return 1; } }; a.x;

Scripted Getter

(Fast on IE) var a = document.getByElementId(“foo”); a.id;

DOM Access

(I only tested .id, so take with a grain of salt--

  • ther properties may differ)

Tuesday, November 8, 2011

slide-90
SLIDE 90

Properties in the Slow Zone

var a = {}; a.x;

Undefined Property

(Fast on Firefox, Chrome) var a = { x: get() { return 1; } }; a.x;

Scripted Getter

(Fast on IE) var a = { x: set(y) { this.x_ = y; } }; a.x = 1;

Scripted Setter

var a = document.getByElementId(“foo”); a.id;

DOM Access

(I only tested .id, so take with a grain of salt--

  • ther properties may differ)

Tuesday, November 8, 2011

slide-91
SLIDE 91

The Typed JIT Compiler

Firefox 3.5+ (Tracemonkey, JM+TI) Chrome 11+ (Crankshaft)

Tuesday, November 8, 2011

slide-92
SLIDE 92

Types FTW!

If only JavaScript had type declarations...

Tuesday, November 8, 2011

slide-93
SLIDE 93

Types FTW!

➡ The JIT would know the type of every local variable

If only JavaScript had type declarations...

Tuesday, November 8, 2011

slide-94
SLIDE 94

Types FTW!

➡ The JIT would know the type of every local variable ➡ Know exactly what action to use (no type checks)

If only JavaScript had type declarations...

Tuesday, November 8, 2011

slide-95
SLIDE 95

Types FTW!

➡ The JIT would know the type of every local variable ➡ Know exactly what action to use (no type checks) ➡ Local variables don’t need to be boxed (or unboxed)

If only JavaScript had type declarations...

Tuesday, November 8, 2011

slide-96
SLIDE 96

Types FTW!

➡ The JIT would know the type of every local variable ➡ Know exactly what action to use (no type checks) ➡ Local variables don’t need to be boxed (or unboxed)

If only JavaScript had type declarations... I call this kind of JIT a typed compiler

Tuesday, November 8, 2011

slide-97
SLIDE 97

But JS doesn’t have types

Tuesday, November 8, 2011

slide-98
SLIDE 98

But JS doesn’t have types

  • Problem: JS doesn’t have type declarations

Tuesday, November 8, 2011

slide-99
SLIDE 99

But JS doesn’t have types

  • Problem: JS doesn’t have type declarations
  • Solution: run the program for a bit, monitor types
  • Bonus points: use static analysis to infer more types

Tuesday, November 8, 2011

slide-100
SLIDE 100

But JS doesn’t have types

  • Problem: JS doesn’t have type declarations
  • Solution: run the program for a bit, monitor types
  • Bonus points: use static analysis to infer more types
  • Then recompile optimized for those types

Tuesday, November 8, 2011

slide-101
SLIDE 101

Running with the Typed JIT

On x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

Firefox 3.5+ Chrome 11+

Tuesday, November 8, 2011

slide-102
SLIDE 102

Running with the Typed JIT

On x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

Firefox 3.5+ Chrome 11+

Tuesday, November 8, 2011

slide-103
SLIDE 103

Running with the Typed JIT

On x = y + z:

  • read the operation x = y + z from memory
  • read the inputs y and z from memory
  • check the types of y and z and choose the action
  • unbox y and z
  • execute the action
  • box the output x
  • write the output x to memory

Firefox 3.5+ Chrome 11+

Tuesday, November 8, 2011

slide-104
SLIDE 104

Further Optimization 1

function getPop(city) { return popdata[city.id]; } for (var i = 0; i < N; ++i) { total += getPop(city); }

Automatic Inlining

  • riginal code

Tuesday, November 8, 2011

slide-105
SLIDE 105

Further Optimization 1

function getPop(city) { return popdata[city.id]; } for (var i = 0; i < N; ++i) { total += getPop(city); }

Automatic Inlining

for (var i = 0; i < N; ++i) { total += popdata[city.id]; }

  • riginal code

JIT compiles as if you wrote this

Tuesday, November 8, 2011

slide-106
SLIDE 106

Further Optimization 2

for (var i = 0; i < N; ++i) { total += a[i] * (1 + options.tax); }

Loop Invariant Code Motion (LICM, “hoisting”)

  • riginal code

Tuesday, November 8, 2011

slide-107
SLIDE 107

Further Optimization 2

for (var i = 0; i < N; ++i) { total += a[i] * (1 + options.tax); }

Loop Invariant Code Motion (LICM, “hoisting”)

var f = 1 + options.tax; for (var i = 0; i < N; ++i) { total += a[i] * f; }

  • riginal code

JIT compiles as if you wrote this

Tuesday, November 8, 2011

slide-108
SLIDE 108

Optimize Only Hot Code

Tuesday, November 8, 2011

slide-109
SLIDE 109

Optimize Only Hot Code

  • Typed JITs have longer compile time
  • which would imply longer startup before JS runs

Tuesday, November 8, 2011

slide-110
SLIDE 110

Optimize Only Hot Code

  • Typed JITs have longer compile time
  • which would imply longer startup before JS runs
  • To avoid this, engines apply typed JITs selectively
  • Only on hot code (~ runs long enough to be measurable)
  • Only if judged to be worthwhile (incomprehensible heuristics)

Tuesday, November 8, 2011

slide-111
SLIDE 111

Current Limitations

Tuesday, November 8, 2011

slide-112
SLIDE 112

Current Limitations

  • What happens if the types change after compiling?
  • Just a few changes -> recompile, slight slowdown
  • Many changes -> give up and deoptimize to untyped JIT

Tuesday, November 8, 2011

slide-113
SLIDE 113

Current Limitations

  • What happens if the types change after compiling?
  • Just a few changes -> recompile, slight slowdown
  • Many changes -> give up and deoptimize to untyped JIT
  • Array elements, object properties, and closed-over variables
  • Usually still boxed, so fast, but not as fast as C!
  • Typed arrays help in theory, but not always optimized in practice yet

Tuesday, November 8, 2011

slide-114
SLIDE 114

Current Limitations

  • What happens if the types change after compiling?
  • Just a few changes -> recompile, slight slowdown
  • Many changes -> give up and deoptimize to untyped JIT
  • Array elements, object properties, and closed-over variables
  • Usually still boxed, so fast, but not as fast as C!
  • Typed arrays help in theory, but not always optimized in practice yet
  • JS semantics require overflow checks for integer math

Tuesday, November 8, 2011

slide-115
SLIDE 115

Type-stable JavaScript

The key to running faster in future JITs is type-stable JavaScript. This means JavaScript where you could declare a single engine-internal type for each variable.

Tuesday, November 8, 2011

slide-116
SLIDE 116

Type-stable JS: examples

var g = 34; var o1 = { a: 56 }; var o2 = { a: 99 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = 0;

Type-stable

Tuesday, November 8, 2011

slide-117
SLIDE 117

Type-stable JS: examples

var g = 34; var o1 = { a: 56 }; var o2 = { a: 99 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = 0;

Type-stable NOT type-stable

var g = 34; var o1 = { a: 56 }; var o2 = { z: 22, a: 56 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = “hello”;

Tuesday, November 8, 2011

slide-118
SLIDE 118

Type-stable JS: examples

var g = 34; var o1 = { a: 56 }; var o2 = { a: 99 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = 0;

Type-stable NOT type-stable

var g = 34; var o1 = { a: 56 }; var o2 = { z: 22, a: 56 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = “hello”; Different shapes

Tuesday, November 8, 2011

slide-119
SLIDE 119

Type-stable JS: examples

var g = 34; var o1 = { a: 56 }; var o2 = { a: 99 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = 0;

Type-stable NOT type-stable

var g = 34; var o1 = { a: 56 }; var o2 = { z: 22, a: 56 }; for (var i = 0; i < 10; ++i) { var o = i % 2 ? o1 : o2; g += o.a; } g = “hello”; Different shapes Type change

Tuesday, November 8, 2011

slide-120
SLIDE 120

Garbage Collection

Tuesday, November 8, 2011

slide-121
SLIDE 121

What Allocates Memory?

new Object(); new MyConstructor(); { a: 4, b: 5 } Object.create();

Objects

new String(“hello”); “<p>” + e.innerHTML + “</p>”

Strings

new Array(); [ 1, 2, 3, 4 ];

Arrays

Tuesday, November 8, 2011

slide-122
SLIDE 122

What Allocates Memory?

new Object(); new MyConstructor(); { a: 4, b: 5 } Object.create();

Objects

new String(“hello”); “<p>” + e.innerHTML + “</p>”

Strings

new Array(); [ 1, 2, 3, 4 ];

Arrays

var x = function () { ... } new Function(code);

Function Objects

Tuesday, November 8, 2011

slide-123
SLIDE 123

What Allocates Memory?

new Object(); new MyConstructor(); { a: 4, b: 5 } Object.create();

Objects

new String(“hello”); “<p>” + e.innerHTML + “</p>”

Strings

new Array(); [ 1, 2, 3, 4 ];

Arrays

var x = function () { ... } new Function(code);

Function Objects

function outer(str) { var name = str; return function inner() { return “Hi, “ + name; } }

Closure Environments

Tuesday, November 8, 2011

slide-124
SLIDE 124

What Allocates Memory?

new Object(); new MyConstructor(); { a: 4, b: 5 } Object.create();

Objects

new String(“hello”); “<p>” + e.innerHTML + “</p>”

Strings

new Array(); [ 1, 2, 3, 4 ];

Arrays

var x = function () { ... } new Function(code);

Function Objects

function outer(str) { var name = str; return function inner() { return “Hi, “ + name; } }

Closure Environments

name is stored in an implicitly created object!

Tuesday, November 8, 2011

slide-125
SLIDE 125

GC Pauses Your Program!

Time JavaScript Running GC Running JS Paused

Tuesday, November 8, 2011

slide-126
SLIDE 126

GC Pauses Your Program!

  • Basic GC algorithm (mark and sweep)
  • Traverse all reachable objects (from locals, window, DOM)
  • Recycle objects that are not reachable

Time JavaScript Running GC Running JS Paused

Tuesday, November 8, 2011

slide-127
SLIDE 127

GC Pauses Your Program!

  • Basic GC algorithm (mark and sweep)
  • Traverse all reachable objects (from locals, window, DOM)
  • Recycle objects that are not reachable
  • The JS program is paused during GC for safe traversal

Time JavaScript Running GC Running JS Paused

Tuesday, November 8, 2011

slide-128
SLIDE 128

GC Pauses Your Program!

  • Basic GC algorithm (mark and sweep)
  • Traverse all reachable objects (from locals, window, DOM)
  • Recycle objects that are not reachable
  • The JS program is paused during GC for safe traversal
  • Pauses may be long: 100 ms or more
  • Serious problem for animation
  • Can also be a drag on general performance

Time JavaScript Running GC Running JS Paused

Tuesday, November 8, 2011

slide-129
SLIDE 129

Reducing Pauses with Science 1

Generational GC

Chrome

Tuesday, November 8, 2011

slide-130
SLIDE 130

Reducing Pauses with Science 1

Generational GC

Idea: Optimize for creating many short-lived objects

Chrome

Tuesday, November 8, 2011

slide-131
SLIDE 131

Reducing Pauses with Science 1

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area

Chrome

Tuesday, November 8, 2011

slide-132
SLIDE 132

Reducing Pauses with Science 1

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

Chrome

Tuesday, November 8, 2011

slide-133
SLIDE 133

Reducing Pauses with Science 1

Simple GC JavaScript Running GC Running JS Paused

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

Chrome

Tuesday, November 8, 2011

slide-134
SLIDE 134

Reducing Pauses with Science 1

Generational GC JavaScript Running Simple GC JavaScript Running GC Running JS Paused

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

Chrome

Tuesday, November 8, 2011

slide-135
SLIDE 135

Reducing Pauses with Science 1

Generational GC JavaScript Running Simple GC JavaScript Running GC Running JS Paused

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

nursery collection (<100 us)

Chrome

Tuesday, November 8, 2011

slide-136
SLIDE 136

Reducing Pauses with Science 1

Generational GC JavaScript Running Simple GC JavaScript Running GC Running JS Paused

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

nursery collection (<100 us) tenured collection

Chrome

Tuesday, November 8, 2011

slide-137
SLIDE 137

Reducing Pauses with Science 1

Generational GC JavaScript Running Simple GC JavaScript Running GC Running JS Paused

Generational GC

Idea: Optimize for creating many short-lived objects Create objects in a frequently collected nursery area Promote long-lived objects to a rarely collected tenured area

nursery collection (<100 us) tenured collection fewer pauses!

Chrome

Tuesday, November 8, 2011

slide-138
SLIDE 138

Generational GC by Example

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-139
SLIDE 139

Generational GC by Example

Point

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-140
SLIDE 140

Generational GC by Example

Point Point

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-141
SLIDE 141

Generational GC by Example

Point Point Line

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-142
SLIDE 142

Generational GC by Example

Point Point Line

a b

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-143
SLIDE 143

Generational GC by Example

Point Point Line

a b

Point

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-144
SLIDE 144

Generational GC by Example

Point Point Line

a b

Point Message

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-145
SLIDE 145

Generational GC by Example

Point Point Line

a b

Point Message

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-146
SLIDE 146

Generational GC by Example

Point Point Line

a b

Point Message Point

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-147
SLIDE 147

Generational GC by Example

Point Point Line

a b

Point Message Point

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-148
SLIDE 148

Generational GC by Example

Message

scavenging young generation (aka nursery) mark-and-sweep tenured generation

Message Message Array

Tuesday, November 8, 2011

slide-149
SLIDE 149

Reducing Pauses with Science 1I

Incremental GC

Chrome

Tuesday, November 8, 2011

slide-150
SLIDE 150

Reducing Pauses with Science 1I

Incremental GC

Idea: Do a little bit of GC traversal at a time

Chrome

Tuesday, November 8, 2011

slide-151
SLIDE 151

Reducing Pauses with Science 1I

Simple GC JavaScript Running GC Running JS Paused

Incremental GC

Idea: Do a little bit of GC traversal at a time

Chrome

Tuesday, November 8, 2011

slide-152
SLIDE 152

Reducing Pauses with Science 1I

Incremental GC Simple GC JavaScript Running GC Running JS Paused

Incremental GC

Idea: Do a little bit of GC traversal at a time

Chrome

Tuesday, November 8, 2011

slide-153
SLIDE 153

Reducing Pauses with Science 1I

Incremental GC Simple GC JavaScript Running GC Running JS Paused

Incremental GC

shorter pauses!

Idea: Do a little bit of GC traversal at a time

Chrome

Tuesday, November 8, 2011

slide-154
SLIDE 154

Reducing Pauses in Practice

Tuesday, November 8, 2011

slide-155
SLIDE 155

Reducing Pauses in Practice

  • For simple GCs
  • Fewer live objects -> shorter pauses
  • Lower allocation rate (objects/second) -> less frequent pauses
  • Lots of live data + allocate objects in hot loops = very bad

Tuesday, November 8, 2011

slide-156
SLIDE 156

Reducing Pauses in Practice

  • For simple GCs
  • Fewer live objects -> shorter pauses
  • Lower allocation rate (objects/second) -> less frequent pauses
  • Lots of live data + allocate objects in hot loops = very bad
  • For incremental GCs
  • Lots of live objects -> slows down program a bit if GC is not generational
  • Mostly, don’t worry about pauses!

Tuesday, November 8, 2011

slide-157
SLIDE 157

JavaScript Engines in Practice

Tuesday, November 8, 2011

slide-158
SLIDE 158

Performance Faults

  • Performance fault: when a tiny change hurts performance
  • Sometimes, just makes one statement slower
  • Other times, deoptimizes the entire function!
  • Reasons we have performance faults
  • bug, tends to get quickly
  • “rare” case, will get fixed if not rare
  • hard to optimize, RSN...

Tuesday, November 8, 2011

slide-159
SLIDE 159

Strings

Tuesday, November 8, 2011

slide-160
SLIDE 160

Strings

  • In the Slow Zone, but some things are faster than you might think

Tuesday, November 8, 2011

slide-161
SLIDE 161

Strings

  • In the Slow Zone, but some things are faster than you might think
  • .substring() is fast, O(1)
  • Don’t need to copy characters, just point within original

Tuesday, November 8, 2011

slide-162
SLIDE 162

Strings

  • In the Slow Zone, but some things are faster than you might think
  • .substring() is fast, O(1)
  • Don’t need to copy characters, just point within original
  • Concatenation is also optimized
  • Batch up inputs in a rope or concat tree, concat all at once
  • Performance fault: prepending (Opera)

Tuesday, November 8, 2011

slide-163
SLIDE 163

Strings

  • In the Slow Zone, but some things are faster than you might think
  • .substring() is fast, O(1)
  • Don’t need to copy characters, just point within original
  • Concatenation is also optimized
  • Batch up inputs in a rope or concat tree, concat all at once
  • Performance fault: prepending (Opera)

// Prepending example var s = “”; for (var i = 0; i < 100; ++i) { s = i + s; }

Tuesday, November 8, 2011

slide-164
SLIDE 164

Arrays

Want a fast array?

  • Make sure it’s dense
  • 0..N fill or push fill is always dense
  • Huge gaps are always sparse
  • N..0 fill is sparse on Firefox
  • adding a named property is sparse
  • n Firefox, IE

var a = []; for (var i = 0; i < 100; ++i) { a[i] = 0; } var a = []; a[10000] = 0; for (var i = 0; i < 100; ++i) { a[i] = 0; } a.x = 7; // Fx, IE only

fast: dense array 3-15x slower: sparse array

Tuesday, November 8, 2011

slide-165
SLIDE 165

Iteration over Arrays

// This runs in all in JIT code, // so it’s really fast. for (var i = 0; i < a.length; ++i) { sum += a[i]; }

fastest: index iteration

Tuesday, November 8, 2011

slide-166
SLIDE 166

Iteration over Arrays

// This runs in all in JIT code, // so it’s really fast. for (var i = 0; i < a.length; ++i) { sum += a[i]; }

fastest: index iteration 3-15x slower: functional style

// This makes N function calls, // and most JITs don’t optimize // through C++ reduce(). sum = a.reduce(function(a, b) { return a + b; });

20-80x slower: for-in

// This calls a C++ function to // navigate the property list. for (var i in a) { sum += a[i]; }

Tuesday, November 8, 2011

slide-167
SLIDE 167

Functions

  • Function calls use ICs, so they are fast
  • Manual inlining can still help sometimes
  • Key performance faults:
  • f.call() - 1.3-35x slower than f()
  • f.apply() - 5-50x slower than f()
  • arguments - often very slow, but varies

Tuesday, November 8, 2011

slide-168
SLIDE 168

Creating Objects

Creating objects is slow Doesn’t matter too much how you create or populate

Tuesday, November 8, 2011

slide-169
SLIDE 169

Creating Objects

Creating objects is slow Doesn’t matter too much how you create or populate Exception: Constructors on Chrome are fast

function Cons(x, y, z) { this.x = x; this.y = y; this.z = z; } for (var i = 0; i < N; ++i) new Cons(i, i + 1, i * 2);

Tuesday, November 8, 2011

slide-170
SLIDE 170

OOP Styling

Tuesday, November 8, 2011

slide-171
SLIDE 171

OOP Styling

function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { distance: function(pt2) ...

Prototype

Tuesday, November 8, 2011

slide-172
SLIDE 172

OOP Styling

function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { distance: function(pt2) ... function Point(x, y) { return { distance: function(pt2) ... } }

Prototype Information-Hiding

Tuesday, November 8, 2011

slide-173
SLIDE 173

OOP Styling

function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { distance: function(pt2) ... function Point(x, y) { return { distance: function(pt2) ... } }

Prototype Information-Hiding

function Point(x, y) { this.x = x; this.y = y; this.distance = function(pt2) ... }

Instance Methods

Tuesday, November 8, 2011

slide-174
SLIDE 174

OOP Styling

function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { distance: function(pt2) ... function Point(x, y) { return { distance: function(pt2) ... } }

Prototype Information-Hiding

function Point(x, y) { this.x = x; this.y = y; this.distance = function(pt2) ... }

Instance Methods Prototype style is much faster to create (each closure creates a function object)

Tuesday, November 8, 2011

slide-175
SLIDE 175

OOP Styling

function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { distance: function(pt2) ... function Point(x, y) { return { distance: function(pt2) ... } }

Prototype Information-Hiding

function Point(x, y) { this.x = x; this.y = y; this.distance = function(pt2) ... }

Instance Methods Prototype style is much faster to create (each closure creates a function object) Using the objects is about the same

Tuesday, November 8, 2011

slide-176
SLIDE 176

Exceptions

  • Exceptions assumed to be rare in perf-sensitive code
  • running a try statement is free on most browers
  • throw/catch is really slow
  • There are many performance faults around exceptions
  • just having a try statement deoptimizes on some browers
  • try-finally is perf fault on some

Tuesday, November 8, 2011

slide-177
SLIDE 177

eval and with

Short version: Do not use anywhere near performance sensitive code!

var sum = 0; for (var i = 0; i < N; ++i) { sum = eval(“sum + i”); }

Mind-Bogglingly Awful

5-100x slower than using a function call var sum = 0; eval(“”); for (var i = 0; i < N; ++i) { sum = eval(“sum + i”); }

Still Terrible

2-10x slower than without eval

Tuesday, November 8, 2011

slide-178
SLIDE 178

Top 5 Things to Know

Tuesday, November 8, 2011

slide-179
SLIDE 179

Top 5 Things to Know

  • 5. Avoid eval, with, exceptions near perf-sensitive code

Tuesday, November 8, 2011

slide-180
SLIDE 180

Top 5 Things to Know

  • 5. Avoid eval, with, exceptions near perf-sensitive code
  • 4. Avoid creating objects in hot loops

Tuesday, November 8, 2011

slide-181
SLIDE 181

Top 5 Things to Know

  • 5. Avoid eval, with, exceptions near perf-sensitive code
  • 4. Avoid creating objects in hot loops
  • 3. Use dense arrays (know what causes sparseness)

Tuesday, November 8, 2011

slide-182
SLIDE 182

Top 5 Things to Know

  • 5. Avoid eval, with, exceptions near perf-sensitive code
  • 4. Avoid creating objects in hot loops
  • 3. Use dense arrays (know what causes sparseness)
  • 2. Write type-stable code

Tuesday, November 8, 2011

slide-183
SLIDE 183

Top 5 Things to Know

  • 5. Avoid eval, with, exceptions near perf-sensitive code
  • 4. Avoid creating objects in hot loops
  • 3. Use dense arrays (know what causes sparseness)
  • 2. Write type-stable code
  • 1. ...

Tuesday, November 8, 2011

slide-184
SLIDE 184

Talk To Us

JS engine developers want to help you. Tell us about:

  • Performance faults you run into
  • Exciting apps that require fast JS
  • Anything interesting you discover about JS performance

Tuesday, November 8, 2011