Live data from Hacker News

V8 Optimization Killers

github.com

61–70 of 88 posts

Re: V8 Optimization Killers

#61
post #53

Which of these (if any) are purely incidental to the current state of the V8 project, rather than being inherently insurmountable problems for JS optimization? In other words, if I memorize this particular list, what subset of my knowledge may become obsolete in a few months or years?

|with| makes reasoning about function behaviour extremely difficult, take:

var x = 5; something.propertyOnSomething = 5 with(something) { x += propertyOnSomething } alert(x); // What is the value of x?

eval() causes problems as it can introduce new variables into the local scope making it logically difficult to reason about program behaviour subsequent to the eval(), e.g.

function f(x) { eval(something); return Math.sqrt(x); }

What is the result of f(9)?

It is possible to set things up to make these not catastrophically harm performance, but the question is whether you would rather the engineers working on these engines make uncommon (and arguably bad) things common, or make normal and frequent code fast. Any time spent working on making uncommon things fast is time not spent making other things fast.

Re: V8 Optimization Killers

#62
post #53

Which of these (if any) are purely incidental to the current state of the V8 project, rather than being inherently insurmountable problems for JS optimization? In other words, if I memorize this particular list, what subset of my knowledge may become obsolete in a few months or years?

> if I memorize this particular list

Please don't memorize this list. It's just for one JS engine among several, all of which are changing rapidly. For example Apple just shipped FTL, an LLVM-based JIT for Safari (so any list for Safari would have just been largely obsoleted).

Re: V8 Optimization Killers

#63
post #62
post #53

Which of these (if any) are purely incidental to the current state of the V8 project, rather than being inherently insurmountable problems for JS optimization? In other words, if I memorize this particular list, what subset of my knowledge may become obsolete in a few months or years?

> if I memorize this particular list Please don't memorize this list. It's just for one JS engine among several, all of which are changing rapidly. For example Apple just shipped FTL, an LLVM-based JIT for Safari (so any list for Safari would have just been largely obsoleted).

> It's just for one JS engine among several

If you are writing code for nodejs, none of the other engines are relevant. If the overwhelming majority of your users are using chrome, then v8-specific optimizations aren't a bad idea.

On the issue of the list, most of the guidelines here apply here and in every other engine. For example, I doubt a future JS engine can optimize `arguments` abuse while preserving ES5 semantics.

Re: V8 Optimization Killers

#64
post #30

Earlier quoted context omitted.

To be fair, many of these apply to other JS engines as well: - manipulating `arguments` should be avoided - when possible, avoid looping over the properties of an object (using `in` or `Object.keys`) In the process of optimizing for v8, you may expose other bad patterns (e.g. megamorphic functions) whose replacement will boost performance everywhere. For example, even though https://github.com/petkaantonov/deque was…

While true, some other bits of advice here (like pulling your try/catch into a separate function) are very V8-specific and may well produce _worse_ code in other implementations. http://jsfiddle.net/G83mW/14/ has a testcase for the try/catch thing that is interesting to compare in different browsers...

[deleted]

Re: V8 Optimization Killers

#65
post #4

Title should probably be "V8 Optimization Killers".

I'm really sick of these recent JavaScript performance related posts that only talk about V8.

Well V8 is the one that matters most. More users use Chrome then Firefox, so it's more important on the client-side. And server-side javascript is probably going to be running on V8. Node.js, Google's scripting platforms, all run V8.

It's like complaining if a C++ performance article only tested with GCC. Sure, there's other compilers out there, but that's the big one.

Re: V8 Optimization Killers

#66
post #62
post #53

Which of these (if any) are purely incidental to the current state of the V8 project, rather than being inherently insurmountable problems for JS optimization? In other words, if I memorize this particular list, what subset of my knowledge may become obsolete in a few months or years?

> if I memorize this particular list Please don't memorize this list. It's just for one JS engine among several, all of which are changing rapidly. For example Apple just shipped FTL, an LLVM-based JIT for Safari (so any list for Safari would have just been largely obsoleted).

I actually don't want to memorize any list, unless it's a list of things that are inherently expensive/impossible to optimize in JS, in which case it's worthwhile. I just hate the idea of having to write all my code according to some list-of-the-week. What I want is a list that separates the always-know stuff from the engine-specific-tweaks or might-not-apply-next-year stuff.

Re: V8 Optimization Killers

#67
post #66
post #62

Earlier quoted context omitted.

> if I memorize this particular list Please don't memorize this list. It's just for one JS engine among several, all of which are changing rapidly. For example Apple just shipped FTL, an LLVM-based JIT for Safari (so any list for Safari would have just been largely obsoleted).

I actually don't want to memorize any list, unless it's a list of things that are inherently expensive/impossible to optimize in JS, in which case it's worthwhile. I just hate the idea of having to write all my code according to some list-of-the-week. What I want is a list that separates the always-know stuff from the engine-specific-tweaks or might-not-apply-next-year stuff.

Actually re-reading the article, I see this:

    Currently not optimizable:

    Generator functions
    Functions that contain a for-of statement
    Functions that contain a try-catch statement
    Functions that contain a try-finally statement
    Functions that contain a compound let assignment
    Functions that contain a compound const assignment
    Functions that contain object literals that contain __proto__, or get or set declarations.

    Likely never optimizable:

    Functions that contain a debugger statement
    Functions that call literally eval()
    Functions that contain a with statement
Which I now realize is sort of what I'm looking for.

Re: V8 Optimization Killers

#68
post #60
post #54

Earlier quoted context omitted.

Compiler optimizations are never perfect. In this case, a compiler would just assume that push could be called and not hoist the length calculation.

JavaScript is complex enough that pretty much any code inside of the loop could end up doing an array push. Even `console.log(myCompletelyUnrelatedObject.x)` (given an evil property descriptor).

I don't know a whole lot about JIT compilers, but would it be possible to emit code with length optimized, and trap changes to it to fall back to a slow path in a way that wouldn't hurt the fast path? For example, you might mark the array so that when other code mutates it, that code also modifies the return address on the stack to point to some fixup code that puts you onto the slow path.

Re: V8 Optimization Killers

#69
post #6

Earlier quoted context omitted.

`for ... in` is a relatively slow construct anyway, the faster option (a lot more verbose) is: var keys = Object.keys(obj), length = keys.length, key, i; for (i = 0; i While this is not exactly the same as for..in, it usually behaves how you'd expect and is significantly faster for a couple of reasons: 1. In a for..in loop the engine must keep track of the keys already iterated over, whereas in the fast version we ca…

Is that (#2) defined behaviour, or is it undefined? Because iirc, other languages disallow it for similar reasons.

Adding properties is undefined in ES5 and I believe defined in ES6.

Deleting properties is guaranteed to not break iteration and deleting an as-of-yet unvisited property causes it to never be visited.

Re: V8 Optimization Killers

#70
post #60
post #54

Earlier quoted context omitted.

Compiler optimizations are never perfect. In this case, a compiler would just assume that push could be called and not hoist the length calculation.

JavaScript is complex enough that pretty much any code inside of the loop could end up doing an array push. Even `console.log(myCompletelyUnrelatedObject.x)` (given an evil property descriptor).

Not if the function is inlineable or an intrinsic (console.log will likely be either), which is the most basic trick of any JIT.

Unless you can specifically measure caching the length is faster, I wouldn't do it. Most of the time it doesn't matter anyway (won't cause a bump in performance), and even then most of the time the compiler will be able to figure it out for you.

Post reply on HN