/
High-Performing High-Performing

High-Performing - PowerPoint Presentation

tawny-fly
tawny-fly . @tawny-fly
Follow
424 views
Uploaded On 2016-12-02

High-Performing - PPT Presentation

JavaScript for Modern Engines Amanda Silver JohnDavid Dalton JavaScript Team Dev 4000 fast and fluid The best apps are The Reach of JavaScript is expanding Web Applications HTML5 Games ID: 495994

type var function bubble var type bubble function javascript fast property prototype code nofbubbles 100 eax performance don

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "High-Performing" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

High-Performing JavaScript for Modern Engines

Amanda Silver, John-David Dalton

JavaScript Team

Dev

4-000Slide2

fast and fluid.

The best apps are…Slide3

The Reach of JavaScript is expanding

Web Applications

HTML5 Games

Windows 8 HTML Apps

Basic Web Pages

JavaScript Execution Speed

DOM Interactions

Accelerated Graphics

Page Load TimeSlide4

WebKit’s JavaScript benchmarkSlide5

Measuring JavaScript performance

JavaScript Execution Performance

Performance of Other

Browser SubsystemsSlide6

HTML5 gamesStress Multiple Browser Subsystems

Bubbles

setInterval(animate, 1000/60)

bs

[

i

] =

new

Bubble(0, 1);for (var i = 0; i < 1000; i++) {

bs[i].move(); for (var j = 0; j < i + 1; j++) { Bubbles.collide(bs[i], bs[j]); }}

var distance2 = (b1.x–b2.x)*(b1.x–b2.x)+(b1.x–b2.x)*(b1.x–b2.x);var magnitude = (

dvx * dx + dvy * dy) / d2;

this.elem.style.left = this

.x + "px";

this

.elem.style.top

=

this

.y

+

"

px

"

;

this

.canvas.getContext

(

"2d")

.

putImageData

(

canvasImageData

, 0, 0);Slide7

Bubbles overviewSlide8

JavaScript in ContextIs Javascript your Bottleneck?Slide9

Is JavaScript the bottleneck?

Networking

HTML

CSS

Collections

JavaScript

Marshalling

DOM

Formatting

Block Building

Layout

Rendering

Is JavaScript your bottleneck?Slide10

Is JavaScript the bottleneck?

Chakra

Your Code

Other SubsystemsSlide11

Do use a good profilerSlide12

Benchmarking with jsPerfSlide13

Do use jsPerf to write micro-benchmarks

Function

declarations go in

preparation

code

or

setupInclude only the bare minimum in each test bodyReset reused shared variables

Don’t introduce randomness in your testDon’t test asynchronous things synchronouslyKnow preparation,

setup, and teardown stagesSlide14

demoEfficient animationSlide15

Don’t do useless work

setInterval

(draw,

0

);

setTimeout

(draw,

0

);requestAnimationFrame(draw);setTimeout

(draw, 1000 / 60);Slide16

Do avoid chattiness with the DOM

JavaScript

DOM

for

(

var

i

= 0; i < this.nOfBubbles; i++) { document.body.box.getElementById("ball0").style.left = b.x + "px"; document.body.box.getElementById(

"ball0").style.top = b.y + "px";}Slide17

demoDOM interactionSlide18

Do check types of values from DOM

this

.nOfBubbles

=

document.getElementById

(“

dropDown

").value;

30%of rendering time in string conversionSlow Operations 11%Value Conversions 18%

GC 17%Your Code 45%Slide19

Don’t

use

a

utomatic

t

ype

c

onversions

BubbleTest.prototype.moveBubbles = function() { for (var i = 0; i < this.nOfBubbles; i++) { this.bubbles[i].move();

} for (var i = 0; i < this.nOfBubbles; i++) { for (var j = i + 1; j < this

.nOfBubbles; j++) { Bubble.prototype.collide

(this.bubbles[i],

this.bubbles[j]); } }

}

this

.nOfBubbles

=

document.getElementById

(“

dropDown

").value;

this

.nOfBubbles

=

parseInt

(

document.getElementById

(

dropDown

"

).value);

BubbleTest.prototype.moveBubbles

=

function

() {

for

(

var

i

= 0;

i

<

this

.nOfBubbles

;

i

++) {

this.bubbles[i].move(); } for (var i = 0;

i < this.nOfBubbles; i++) { for (var j = i + 1; j < this.nOfBubbles; j++) { Bubble.prototype.collide(this.bubbles

[i], this.bubbles[j]); } }}“128”128Slide20

Do

parse

n

umbers from strings

this

.nOfBubbles

=

parseInt

(document.getElementById(“dropDown").value);GC 28%

Your Code 64%Slide21

JavaScript: Flexibility or performance

Flexibility

Performance

“Think C++”

“Think Script”

Simple Websites

Complex Apps, Games

var

r = 3 * "10"; // r == 300var a = new Array();a.push(10);var p = {x: 0, y: 0};p.z = 5;

p["some text"] = 1;p[1] = 2;eval("var s = p[1] * a[0]"); // s == 20var r = 3 * parseInt("10"); var a = new Array(100);a[0] = 10;

var p = new Point(0, 0, 0);p.z

= 5;Slide22

Lifecycle of your JavaScript code

Core #1

Foreground

Interpreter

Byte Code

AST

Parser

Source Code

Core #2

BackgroundNative Code

Background CompilerSlide23

Create fast objectsSlide24

demoFast property accessSlide25

Fast property access

if

(b1.bubbleBounceCounter >= 10) {

delete

b1.bubbleBounceCounter;

}

Slow Property Access 41%

if

(b1.bubbleBounceCounter >= 10) { b1.bubbleBounceCounter = 0;}Slide26

Objects in JavaScript

var

base = { color:

"red"

};

base.x

= 10;base["any string"] = 0;for

(var p in base) {...}

function Bubble() {...}Bubble.prototype = base;var b = new Bubble();var c = b.color; // c == "red“b.y = 20;var x = b.x; // x == 10delete base.x;var u =

b.x; // u == undefinedproperty bags, no classesadd properties on the flyclass-like patternprototypal inheritance

even remove properties

enumerate propertiesuse as dictionaries

but still just property bags

Flexibility

Performance

Use Property Bags

Think: “Objects and Classes”Slide27

b1.type

b2.type

Bubble

“x”

“y”

y

Bubble

“x”

x

Bubble

10

11

10

b2

0

1

0

b1

function

Bubble(x, y) {

this

.x

= x;

this

.y

= y;

}

var

b1 =

new

Bubble(0, 1);

var

b2 =

new

Bubble(10, 11);

Internal fast

t

ype

s

ystemSlide28

b1.type

b2.type

Bubble

“x”

“y”

“c”

c

Bubble

“x”

“y”

y

Bubble

“x”

x

Bubble

10

11

“red”

10

11

b2

0

1

b1

function

Bubble(x, y) {

this

.x

= x;

this

.y

= y;

}

var

b1 =

new

Bubble(0, 1);

var

b2 =

new

Bubble(10, 11);

b2.c =

"red"

;

Internal fast

t

ype

s

ystemSlide29

Do add all properties

in c

onstructor

Avoid

slow

property bags

function

Point() { this.x = 0;

this.y = 0;}var p1 = new Point();p1.prop01 = 1;...p1.prop99 = 99;

b1.type = fast-type({x,y})too many properties?b1.type = slow-property-bagSlide30

Don’t delete properties

Avoid

slow

p

roperty

bags

function Point() {

this.x = 0; this

.y = 0;}var p1 = new Point();delete p1.y;b1.y = undefined;

b1.type = fast-type({x,y})deleting properties?b1.type =

slow-property-bag

b1.type ==

fast-type({x,y})Slide31

Do use identifiers

for

property

n

ames

Avoid slow property b

ags

function Point() { this.x = 0;

this.y = 0;}var p1 = new Point();p1["some text"] = 1;

b1.type = fast-type({x,y})non-identifier properties?b1.type = slow-property-bagSlide32

Don’t use getters & s

etters

e

xcessively

Avoid

slow property b

agsfunction

Bubble(x, y) { Object.defineProperty(this

, "x", { get : function() { return x; }, set : function(value) { x = value; }, }); Object.defineProperty(this, "y", { get : function() { return y; }, set : function(value) { y = value; },

});}var b = new Bubble(0, 1);var x = b.x;b.y = 5;getters & setters?b.type =

slow-property-bagSlide33

Don’t add properties c

onditionally

Avoid Fast Type Mismatches

function

Color(alpha) {

this.r = 0;

this.g = 0; this

.b = 0; if (alpha) { this.a = 0; }}var c1 = new Color(true);var c2 = new Color(false);

c1.type = {r,g,b,a}c2.type = {r,g,b

}Slide34

function

TreeNode

(key, value) {

this.key

= key; this.value = value;

};TreeNode.prototype.left = null;

TreeNode.prototype.right = null;var t1 = new TreeNode("k1", "v1");var t2 = new TreeNode("k2", "v2");var t3 = new

TreeNode("k3", "v3");t1.left = t2;t2.right = t3;

Don’t default properties on prototypes

Avoid Fast Type MismatchesSlide35

Property access works in C++ or C#

class

Bubble

{

public int

x; public int y;

}class Program { static void Reset(Bubble b) { b.x = 0; b.y = 0; }}

mov edx, 0mov  eax, [p]mov [p+4],

edxSlide36

Fast property access in JavaScript

function

Bubble(x, y) {

this

.x

= x; this

.y = y;}function

Bubble.prototype.reset() { this.x = 0; this.y = 0;}

mov eax, 0x00000001mov    ebx

, [this]

mov    ecx

, [this.type]cmp

    ecx, [

ic.type

]

jne

    $

callSetProperty

mov

    

ecx

, [

this.propArray

]

mov

edx

, [

ic.index

]

mov

    [

p.propArray

[

ic.index

]

],

eax

// 100s of assembly instructions

engine.LookUpProperty

(this, x)

engine.SetProperty

(this, x, 0)

inline cache

type

prop indexSlide37

function

Bubble(x, y) {...}

function

Bubble.prototype.reset

() {

this.x = 0; this

.y = 0;}var b1 =

new Bubble(0, 1);var b2 = new Bubble(10, 11);for (var i = 0; i < 1000; i++) { bubbles[i].reset();}Fast property access works

For objects of matching fast types

inline cache

0

0

mov

eax

, 0x00000001

mov

  

ebx

, [this]

mov

  

ecx

, [

this.type

]

cmp

  

ecx

, [

ic.type

]

jne

  $

callSlowSetProperty

mov

  

ecx

, [

this.propArray

]

mov

edx

, [

ic.index

]

mov

  [

p.propArray

[ic.index]], eax

b1.type = “{x,y}”

b2.type = “{x,y}”b1.type = “{x,y}”

b2.type = “{x,y}”“{x, y}”1Slide38

function

Bubble(x, y) {...}

function

Bubble.prototype.reset

() {

this.x = 0; this

.y = 0;}var

b1 = new Bubble(0, 1);var b2 = new Bubble(10, 11);b2.c = "red";for (var i = 0; i < 1000; i++) { bubbles[i].reset();}

Fast property access failsFor objects of mismatched fast types or property bags

inline cache

0

0

mov

eax

, 0x00000001

mov

  

ebx

, [

this

]

mov

  

ecx

, [

this.type

]

cmp

  

ecx

, [

ic.type

]

jne

  $

callSlowSetProperty

mov

  

ecx

, [

this.propArray

]

mov

edx

, [

ic.index

]

mov

  [p.propArray[ic.index]], eax

b1.type = “{

x,y}”b2.type = “{x,y,c}”

b1.type = “{x,y}”b2.type = “{x,y,c}”“{x, y}”

1

“{x, y, c}”Slide39

Do write fast objects

Add all properties in constructor

Don’t delete properties

Use identifiers for property names

Use getters and setters sparingly

Avoid conditionally adding propertiesAvoid default property values on prototype objectsSlide40

JavaScript ArithmeticSlide41

What is causing garbage collection?

Bubble.prototype.move

=

function

(

elapsedTime

) { this

.x += this

.vx * elapsedTime / model.animationFrameDuration; this.y += this.vy * elapsedTime / model.animationFrameDuration;}

Garbage Collection25%Slide42

JavaScript arithmetic is very permissiveExtreme

f

lexibility

+ …

function

doMath(a, b, c, d) {

return a * b + c * d;}var

a = 3;var b = "10";var c = new Date();var d = {valueOf: function() { return 5; }}var r = doMath(a, b, c, d);

r == 6640403003390Flexible? YesFast? NoSlide43

JavaScript values are dynamically typedExtreme

f

lexibility

+

dynamic typing

= …var

a = 3;a = 2.5;a = "text";

a = { x: 0, y: 1};a = new Date();var b = getSomeValue();var c = someObject.c;function doSomething(a, b, c) { global.r = a + b + c;}a

b

c

Number

3

Object

0

1

Number

2.5

String

“text”

Date

heap

stackSlide44

Generic JavaScript arithmetic is slowExtreme

f

lexibility

+

dynamic typing =

slow & complex algorithm

return a + b + c;

av = getValueFromHeap(a)bv = getValueFromHeap(b)at = getType

(a)bt = getType(b)op = selectOperation(at, bt)

rv1 = op(

av, bv)

r1 =

boxOnHeap(rv1)

r1 =

doPlus

(a, b)

r2 =

doPlus

(r1, c)

return r2Slide45

Do use integer math to avoid

b

oxing

var

a = 3;

var

b = "text";var

c = 2.5;var d = 0x80000000;function

doSomething(a, b, c, d) { global.r = a + b + c + d;}doSomething(a, b, c, d);stack0x00000007a:0x005e4148

b:0x005e4160c:String“text”

Number

2.5

Number

0x80000000

0x005e4170

d:

Number

3

heap

0x005e4148: 0…01001

000

0x07 represents 3:  0…0000011

1Slide46

Do use floating p

oint

m

ath

j

udiciously

var a = 5;var b = 2;var

r = ((a + b) / 2) | 0; // r = 3var r =

Math.round((a + b) / 2); // r = 4var a = 5;var b = 2;var r = (a + b) / 2); // r = 3.5stack0x005e4148r:

0x00000007r:0x00000009r:Number

3.5

heapSlide47

Type-specialized code generation

Generic

Machine Code

Chakra

Helper Code

Type Specialized

Machine Code

Chakra

InterpreterSlide48

Type specialized functions are f

ast

But

r

equire consistent

input arguments

function (b1, b2) { var

dx = b1.x - b2.x; var dy = b1.y - b2.y; var dvx = b1.vx - b2.vx; var dvy = b1.vy - b2.vy; var d2 = dx * dx + dy * dy; var mag = (dvx * dx +

dvy * dy) / d2; var delta_vx = dx * mag; var delta_vy = dy * mag; b1.vx -= delta_vx; b1.vy -= delta_vy;

b2.vx += delta_vx; b2.vy += delta_vy

;}stack

0.10

d2

2.49

mag

0.05

delta_vx

0.25

delta_vy

registers

2.70

eax

(dx)

10.50

1.00

0.55

ebx

(

dy

)

ecx

(

dvx

)

edx

(

dvy

)Slide49

Do use arguments of

consistent

t

ypes

function

(b1, b2) {

(...) var dx = b1.x - b2.x;

var dy = b1.y - b2.y; ...

var d2 = dx * dx + dy * dy; ...}Bubble.prototype.collide(b1, b2);for (var i = 0; i < nOfBubbles; i++) { for (var j = i + 1; j < nOfBubbles; j++) { Bubble.prototype.collide

(bs[i], bs[j]); }}

MOV

eax, dxMOV ebx

, dy

MUL eax, eax

MUL

ebx

,

ebx

ADD

eax

,

ebx

// d2 in

eax

now

if (b1.type != Bubble) bail out;

if (b1.x.type != “float”) bail out;

if (b2.type != Bubble) bail out;

if (b2.x.type != “float”) bail out;

...Slide50

Do use fast type-specialized arithmetic

Be

aware of number

boxing

Avoid unnecessary floating point math

Enable type-specializing JIT compilersSlide51

JavaScript ArraysSlide52

Number boxing in JavaScript arrays

this

.gaussianMask

=

new

Array

(

maskSize * maskSize);this.occlusionMask = new Array(canvasWidth * canvasHeight);Garbage Collection90% of 1 CPU

this.gaussianMask = new Float64Array(maskSize * maskSize);this.occlusionMask = new Float64Array(canvasWidth *

canvasHeight);Slide53

DemoTyped arrays and boxingSlide54

Do take advantage of typed arrays

var

value = 5;

var

a =

new

Array(100);

a[0] = value; // a[0] == 5 (tagged)a[1] = value / 2; // a[1] == 2.5 (boxed)

a[2] = "text"; // a[2] == "text"var a = new Uint32Array(100);a[0] = value; // a[0] == 5 ("naked", no tagging required)a[1] = value / 2; // a[1] == 2 ("naked", no tagging required)a[2] = "text"; // a[2] == 0var a = new Float64Array(100);a[0] = value;

// a[0] == 5 ("naked", no tagging required)a[1] = value / 2; // a[1] == 2.5 ("naked", no boxing required!)a[2] = "text"; // a[2] == 0flexibilityperformanceSlide55

Don’t use objects as arraysOr

vice

v

ersa

var

b =

new

Bubble(0, 1);for

(var i = 0; i < 100; i++) { b[i] = i + 2;}var a = new Array(100);for (var i = 0; i < 100; i++) { a[i] = i + 2;}

convenienceperformanceSlide56

Do pre-allocate arrays

var

a =

new

Array(100);

for

(var i = 0; i < 100; i++) { a[

i] = i + 2;}

var a = new Array();for (var i = 0; i < 100; i++) { a.push(i + 2);}convenience

performance

0

?

?+1

??

0

100Slide57

Do enumerate arrays efficiently

var

a =

new

Array(100);

var

total = 0;

for (var item in

a) { total += item;};a.forEach(function(item) { total += item; });for (var i = 0; i < a.length; i++) { total += a[i];}for (var i = 0, len = a.length

; i < len; i++) { total += a[i];}convenienceperformanceSlide58

Do use arrays efficiently

Don’t use objects as arrays and vice

versa

Pre-allocate on

creation

Enumerate efficiently

Use typed arrays to avoid float boxingSlide59

In-review: Write fast JavaScript

Use good performance tools

Identify and focus on your bottlenecks

Understand and target modern engines

Create fast objects

Write fast arithmeticUse arrays efficientlySlide60

Go forth and code it! 3-012: Introducing TypeScript: A language for application-scale JavaScript development

3-020: Building

apps for Office and SharePoint 2013 using the web technologies you know and

love

3-115: Intro to creating Windows Store apps using HTML and JavaScript

4-101: Deep dive into WinJS

3-008: Diagnosing perf and memory issues in JavaScript-based Windows Store apps3-014: Modern JavaScript3-018:

TouchDevelop: A touch-first IDE for the Web created with TypeScript3-041: Javascript from client to cloud with Windows 8, Node.js, and Windows Azure

3-130: Writing Windows Store apps with jQuery2-015: Windows Phone 8: HTML5/IE10 for Developers jsperf.com blogs.msdn.com/b/ie/ Slide61