News for hackers. Stuff that matters.
Re:Maybe you don't need Rust and WASM to speed up your JS by anp on Monday February 19, 2018 @01:04PM (#16414450)
I think this is an interesting exploration because I really enjoyed the description of profiling and improving performance, but I came away feeling exactly the opposite of the title. I think it's really cool that JS optimization can provide so many wins, but this article makes it seem fairly fickle and if they're not familiar with VM internals I would not expect most developers to complete this journey. Using wasm+rust/c++ is interesting in part because you can get so much more predictable performance out of the box. When the performance comes from language features instead of VM-specific optimizations the performance might be easier to maintain across revisions and hopefully will be less subject to regression from VM changes.
Re:Maybe you don't need Rust and WASM to speed up your JS by mraleph on Monday February 19, 2018 @02:31PM (#16415076)
[Thank you for reading the post! I am glad you enjoyed it]

All optimizations in the post can mostly be divided into three large groups:

1) algorithmic improvements; 2) workarounds for implementation independent, but potentially language dependent issues; 3) workarounds for V8 specific issues;

You need to think about algorithms no matter which language you write in, so we don't need to talk much about the first group. In the post it is represented by sorting improvements (sorting subsequences rather than the whole array) and by discussions of caching benefits (or lack of them there-off).

The second group is represented by a monomorphisation trick: the fact that the performance suffers due to polymorphism is not really a V8 specific issue and it is not even JS specific issue. You can apply this approach across implementations and even languages. Some languages apply it in some form for you under the hood.

The last group is represented by argument adaptation stuff.

Finally an optimization I did to mappings representation (using typed array instead of an object) is an optimization that spans all three groups. It's about understanding limitations and costs of a GCed system as whole.

Now... Why did I choose the title? That's because I think group #3 represents the issue that should and would be mostly fixed over time. While groups 1 and 2 represent universal knowledge that spans across implementations and languages.

Obviously it is up to each developer and each team to choose between spending N rigorous hours profiling and reading and thinking about their JavaScript code, or to spend N hours rewriting their stuff in a language X. What I want is:

a) that everybody was fully aware that the choice even exists; b) language designers and implementors worked together on making this choice less and less obvious - which means working on language features and tools and reducing the need in group #3 optimizations.

Re:Maybe you don't need Rust and WASM to speed up your JS by vanderZwan on Monday February 19, 2018 @05:07PM (#16416144)
> monomorphisation trick

Here's a crazy thing I recently learned: apparently monomorphism isn't just "object with identical keys", apparently (at least in Chrome), the order in which you declare those keys matters. According to this presentation from 2015[0], adjusting the following lines in the Octane/Splaytree benchmark so that node.left and node.right are always assigned in the same order resulted in 15% better performance:

    var node = new SplayTree.Node(key, value);
    if (key > this.root_.key) {
      node.left = this.root_;
      node.right = this.root_.right;
      ...
    } else {
      node.right = this.root_;
      node.left = this.root_.left;
      ...
    }
Now, I assume that this out-of-order thing was actually done on purpose, to benchmark how the JIT handles code like this. Further evidence for that is that the SplayTree constructor[1] does not feature a left and right key either:

    SplayTree.Node = function(key, value) {
      this.key = key;
      this.value = value;
    };
Still, I wouldn't be surprised if it was common for real-life code to accidentally have objects that should have the same hidden class end up with different ones because of this.

[0] http://mp.binaervarianz.de/fse2015_slides.pdf

[1] https://github.com/chromium/octane/blob/master/splay.js#L390

Re:Maybe you don't need Rust and WASM to speed up your JS by ridiculous_fish on Monday February 19, 2018 @05:32PM (#16416293)
Yes, this is because the JS spec requires that object keys are iterated in insertion order (with a bizarre exception for arrays).
Re:Maybe you don't need Rust and WASM to speed up your JS by vanderZwan on Monday February 19, 2018 @06:55PM (#16416759)
Ah, I guess that explains it. Although that does not require the engine to have under-the-hood layout respect that, does it? They could just as easily choose to keep the memory layout in the same order.

Although I suppose you're already required to have two separate hidden classes to distinguish these two kinds of objects anyway.

> with a bizarre exception for arrays

Wow, you weren't joking with how bizarre this gets:

    var a = {};
    var b = {};
    a.a = 0;
    a.b = 1;
    a[0] = 0;
    a[1] = 1;
    b.b = 1;
    b.a = 0;
    b[1] = 1;
    b[0] = 0;
    Object.keys(a); // Array [ "0", "1", "a", "b" ]
    Object.keys(b); // Array [ "0", "1", "b", "a" ]
PS: Thanks for making a great shell :)
Re:Maybe you don't need Rust and WASM to speed up your JS by sayrer on Monday February 19, 2018 @08:42PM (#16417237)
Prior to Chrome's release, browsers preserved insertion order for numeric keys as well (but this was not in the ES3 spec).

Chrome/V8's team found they could get substantial performance improvements by diverging from the de facto standard, without too much of a cost to web compatibility.

Re:Maybe you don't need Rust and WASM to speed up your JS by deathanatos on Tuesday February 20, 2018 @12:55AM (#16418148)
TIL. For those like me for which this is new, this was apparently a change in the ES 2015 / ES 6 version of the standard.

See: https://stackoverflow.com/questions/5525795/does-javascript-...

The order is only sometimes guaranteed, of course, because JavaScript. (But critically, for this discussion, it is important that it is sometimes guaranteed, because it forces that information to be stored by the VM.)

Re:Maybe you don't need Rust and WASM to speed up your JS by vanderZwan on Tuesday February 20, 2018 @06:58AM (#16419688)
I feel so justified in adding this guard in my compression pre-processor[0] code, even though I never had a bug without it:

    // the keys of an object
    export function keysOf(obj) {
      let keys = Object.keys(obj);
      keys.sort();
      return oneOf(keys);
    }
Context: the rest of the code takes an object representing a schema, and creates two functions. One that can turn any object fitting that schema into an array, with positions indicating which key they originally belonged to, and another one that can reverse the process.

Could this also explain why I have no consistent order of properties when viewing state with the Redux dev-tools? Instead of Object.assign I use my own simplified merge code[1]. Maybe if I also make that use a sorted set of keys, the devtools will become more consistent in their presentation (and it might result in more consistent hidden classes too).

[0] https://github.com/linnarsson-lab/loom-viewer/blob/master/cl...

[1] https://github.com/linnarsson-lab/loom-viewer/blob/master/cl...

Re:Maybe you don't need Rust and WASM to speed up your JS by pdpi on Tuesday February 20, 2018 @08:53AM (#16420276)
Wait what? Since when? That wasn’t the case at all 5 or 6 years ago (I got bitten in the arse by Rhino not implementing it that way)
Re:Maybe you don't need Rust and WASM to speed up your JS by epmatsw on Tuesday February 20, 2018 @10:33AM (#16421073)
Most browsers already did, and some (not all) of the ES2015 stuff requires property ordering. Probably easier to just keep everything ordered since it could be needed by those methods.
Re:Maybe you don't need Rust and WASM to speed up your JS by zbentley on Monday February 19, 2018 @03:02PM (#16415288)
> Some languages apply it in some form for you under the hood.

I suspect some respondents will say, or believe, that this falls under the category of "you have to know the VM/runtime intimately to get good performance".

I don't think that's true. If you know the general problems with polymorphic call sites, you can (in JS and many other languages) check to see if the runtime is applying optimizations of this kind by being explicit. If it helps, you can get a free optimization by setting explicit arity/dispatch just because you happened to know about the issues surrounding polymorphic dispatch. That's a case of fundamental knowledge speeding up/improving your progress; not a case of "you need to know the VM guts like the back of your hand to make code fast".

Re:Maybe you don't need Rust and WASM to speed up your JS by TAForObvReasons on Monday February 19, 2018 @10:47PM (#16417705)
Ultimately, much of the enthusiasm over WASM, like ASM.JS, is rooted in the idea that it's extremely difficult to improve JS engine performance. ASM.JS used certain conventions to essentially create a "language within JS", while WASM is a new language altogether. The goal was the same in both cases: construct a language that is easier to optimize and make the end users conform.

The key takeaway of your commentary on asm.js five years ago (http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html) is the same as the key takeaway from this post: we haven't reached the end of JS engine performance improvements, and if we apply the same rigor to JS development that we apply to C++ or C or Rust or some other language the results are definitely surprising!

Re:Maybe you don't need Rust and WASM to speed up your JS by jandem on Monday February 19, 2018 @01:13PM (#16414511)
I work on SpiderMonkey JS performance (and got mentioned in the article for fixing a perf bug!) and this is exactly the point I wanted to make. If you're not a VM engineer, it's much harder to write fast JS. Wasm also gives you much more predictable performance across engines, without requiring (often engine-specific) 'hacks' like function cloning.
Re:Maybe you don't need Rust and WASM to speed up your JS by Jasper_ on Monday February 19, 2018 @01:44PM (#16414725)
From what I can tell, doing basic things like a property get on an object in WASM/host-bindings will require a spill to function, with no chance of specialization:

https://github.com/WebAssembly/host-bindings/issues/11#issue...

If you think the assembly in this article is bad, WASM/host-bindings appear to be even worse.

Re:Maybe you don't need Rust and WASM to speed up your JS by luke_wagner on Monday February 19, 2018 @02:31PM (#16415077)
That comment (which I made) explains why probably the best we can expect for wasm accessing normal JS objects is the same level of speed as a modern JS engine's "tier 1"/"baseline" JIT. But the Rust code discussed in the OP wasn't accessing JS objects, it was accessing Rust memory which lives in wasm's "linear memory", so I don't see how my comment really disagrees with what jandem or dikaiosune are saying.
Re:Maybe you don't need Rust and WASM to speed up your JS by aschampion on Monday February 19, 2018 @01:17PM (#16414533)
Having micro-optimized and maintained JS code over years and dozens of browser versions, I cannot echo this enough. Tuning JS both the in face of fickleness of VM quirks and data/context is a losing proposition for all but the most speed- and core-functionality-critical code.

The point of rust+wasm benchmarks is that one can write reasonable, maintainable, functionality-focused code (not to mention all the rust-specific benefits) and get good performance out of the box.

Re:Maybe you don't need Rust and WASM to speed up your JS by zbentley on Monday February 19, 2018 @03:05PM (#16415306)
Writing an O(N^2) algorithm that processes lots of data in wasm is not going to speed it up more than writing an O(log N) algorithm in pure JS; the knowledge of how to identify problems like that will serve you better in many more cases than the selection of a "fast" runtime.
Re:Maybe you don't need Rust and WASM to speed up your JS by vvanders on Monday February 19, 2018 @10:32PM (#16417654)
Not totally true, some algos while large O(n) are incredible cache friendly.

Radix sort for instance comes to mind.

Re:Maybe you don't need Rust and WASM to speed up your JS by b0rsuk on Monday February 19, 2018 @03:53PM (#16415654)
I'm afraid it's easier to get started as a Javascript developer than a Rust developer. What if it's easier to learn JS optimization quirks than to become an average Rust developer ?
Re:Maybe you don't need Rust and WASM to speed up your JS by kbenson on Monday February 19, 2018 @04:15PM (#16415810)
It's a cost/benefit type of situation. Learning to optimize JavaScript might cost less, but the benefit is fairly narrow, and may lesson over time (or you may need to pay more in attention and time to keep up with JavaScript VM changes). Rust (or C++) to WASM costs more (if you don't already know the language), but the benefit should stay static and useful over time, and there are many other benefits as well (such as having a fast low-level language to fall back on for other needs.

This isn't unique to this situation either. If you're writing Python and your choice is to either deep dive into various hacks to maximize performance of your pure python or learn Rust/C/C++ and call out using an FFI mechanism, if you have the time to space, I think it's almost always better to learn the new language. There are many benefits to learning new languages beyond just the different performance characteristics, so if you can afford to take that path, I think it's usually a good choice to do so.

Re:Maybe you don't need Rust and WASM to speed up your JS by b0rsuk on Monday February 19, 2018 @11:50PM (#16417921)
I agree with this, but I think most people don't, until it's demonstrated Rust kicks ass. Javascript is all the age right now. People might think "I'll get a Javascript job now, and I will learn to optimize later. Javascript is highly optimized anyway." Then it's just inertia. They already know Javascript. Besides, Javascript may have a reputation for being messy, but not for being a hard language to pick up. Yes it does have an unusual OO style, and supports functional programming, but you don't have to start with high level topics just to write any code with it.

As far as I know Rust has just two major success stories right now: Firefox 57 (Servo) ripgrep (even included in Microsoft Visual Studio)

Re:Maybe you don't need Rust and WASM to speed up your JS by steveklabnik on Tuesday February 20, 2018 @08:29AM (#16420123)
> As far as I know Rust has just two major success stories right now

Here's a bunch more. Dunno what your definition of "major" is though: https://www.rust-lang.org/en-US/friends.html

Re:Maybe you don't need Rust and WASM to speed up your JS by kbenson on Tuesday February 20, 2018 @12:41AM (#16418104)
Sure, and that's why I was careful to couch the argument as just some other language that includes C and C++ as options (and truthfully includes others, but few have quite the same compatibility story). At this point if you don't know C++ or Rust, which one will give you the most benefit from learning it is a very open question. I think Rust has advantages over C++ in correctness and safety, but C++ currently offers better paths for understanding and utilizing existing code or getting a job using it (whether that was an initial goal or not). Five years down the line the differences may not be so cut and dry though. C++ will almost definitely still have those advantages, but the gap have have closed somewhat. Or maybe not? It's all up in the air.
Re:Maybe you don't need Rust and WASM to speed up your JS by pjmlp on Tuesday February 20, 2018 @06:04AM (#16419408)
Currently C++ still wins over Rust, regarding UI and mobile development, specially in what concerns out-of-box experience.

C++ had the advantage of being immediately adopted by the OS vendors for GUI development, although nowadays, with exception of Windows, its role has changed into just addressing the GPU.

So maybe one day we will get something like shaders, CoreGraphics, DirectX, SurfaceFlinger in Rust, but it will still need a couple of years.

Webrender is already something into this direction.

Re:Maybe you don't need Rust and WASM to speed up your JS by carlmr on Tuesday February 20, 2018 @05:49AM (#16419327)
>but C++ currently offers better paths for understanding and utilizing existing code or getting a job using it

I wouldn't say this is entirely wrong, but proper cross-platform package and test management with Cargo is a reason alone that utilizing existing code is waaay easier in Rust. C++ has more existing code though, so they might hit your niche needs better.

Re:Maybe you don't need Rust and WASM to speed up your JS by pjmlp on Tuesday February 20, 2018 @06:06AM (#16419417)
Here something like conan might finally win the hearts of C++ devs, but it is still pretty much in the beginning.

In what concerns Windows development, NuGET and vcpkg are already a big improvement.

Re:Maybe you don't need Rust and WASM to speed up your JS by carlmr on Tuesday February 20, 2018 @06:10AM (#16419452)
NuGet is pretty good, I've only used it with C#/F# though.
Re:Maybe you don't need Rust and WASM to speed up your JS by swsieber on Tuesday February 20, 2018 @12:48AM (#16418122)
Does drop box writing a fs in Rust count as a major success story?
Re:Maybe you don't need Rust and WASM to speed up your JS by b0rsuk on Tuesday February 20, 2018 @01:36AM (#16418273)
It doesn't count as a major success story I knew about when I was typing that comment.
Re:Maybe you don't need Rust and WASM to speed up your JS by hateduser2 on Monday February 19, 2018 @04:00PM (#16415705)
It seems less reliable to learn is optimization quirks, since you’re depending on an (infrequently changing?) implementation detail. Also writing those things sounds muh messier and less maintainable. All heuristic points I’m making.
Re:Maybe you don't need Rust and WASM to speed up your JS by Cthulhu_ on Tuesday February 20, 2018 @07:31AM (#16419839)
And yet, which is better; finding someone that has the skill and knowledge needed to optimize this (e.g. bring in a consultant), or rewrite the thing - hundreds if not thousands of lines of code and working hours being replaced by even more. And not just rewrite it, but (IMO) replacing it with more complicated technology (additional steps required to make it usable, additional skills needed to work on the project).

I think people think too lightly of rewrites. Actually, I'd even argue that in some cases, rewrites are done because they're easier than actually fixing the problem. Yes, Rust and other languages will give you better performance out of the box, but at what cost?

Re:Maybe you don't need Rust and WASM to speed up your JS by dikaiosune on Tuesday February 20, 2018 @10:01AM (#16420787)
Like any situation in software, there are likely to be tradeoffs. I certainly wouldn't advocate for launching large rewrites except under extreme duress. That said, I'm not sure I agree with how you're characterizing the tradeoffs for using wasm here. For one thing, the library in question sounds like it is a few thousand lines, not some gargantuan project. For another, part of what's awesome about wasm is that it can be somewhat incrementally adopted inside an existing project. I would also point out that for many teams or projects maintaining a consultant's code is not going to be as cost effective in the long run, especially if that code has a lot of language or VM specific optimizationswork done to it. Part of my point here is that the addition of new tech (rust, wasm) isn't complicated where optimizing JS is simple, but that they both carry complexity cost and should be assessed in context as possible solutions to a performance problem.

I agree that rewrites are often taken too lightly, but if they address the original problems I think it would be more accurate to say that they are often needlessly expensive ways to solve problems that can also be solved in other, cheaper ways.

I'd also point out that in the case of many open source projects, finding an optimization consultant is not even remotely an option. For many of those projects, if performance is suffering, someone needs to step up and figure something out. Then the question becomes which approach can be applied by some contributor who's actually willing to do it. If you don't have someone who understands polymorphism in VM runtimes, I think in many cases you'd be well served by sprinkling some wasm on the problem. Of course this doesn't apply in all cases.

Re:Maybe you don't need Rust and WASM to speed up your JS by mpweiher on Monday February 19, 2018 @05:01PM (#16416104)
> cool optimizations ... but ... fickle ... internals ...

Yes. I wrote about this in some detail 2 years ago, Jitterdämmerung:

http://blog.metaobject.com/2015/10/jitterdammerung.html