News for hackers. Stuff that matters.
Re:A first look at WebAssembly performance by Derbasti on Thursday February 09, 2017 @04:20AM (#13605658)
The way I understand it, WebAssembly is all about the size of the binary and parsing overhead. Or, at a higher level, about enabling a level playing field between more languages than just JavaScript.

Speed improvements from a common runtime and bytecode are certainly welcome, but if they are possible with WebAssembly, they are also be possible with plain JavaScript, and therefore shouldn't be visible in a comparison between the two.

I, for one, hope that WebAssembly will enable, say, Lua as a first class citizen on the web.

Re:A first look at WebAssembly performance by hacker_9 on Thursday February 09, 2017 @05:31AM (#13605939)
> Speed improvements from a common runtime and bytecode are certainly welcome, but if they are possible with WebAssembly, they are also be possible with plain JavaScript

Nope, a static language will execute faster than a dynamic language, because the runtime knows precisely what type everything is and how much space to allocate. Additionally no faffing around with dictionaries for dynamic types. Currently JS engines will have to figure out the types dynamically at runtime, but even then can't always be sure so have to keep to slower dictionary lookups.

Once we have a static language -> webasm, it should execute an order of a magnitude faster than JS -> webasm.

Edit: Additionally, browsers will finally consume less power, CPU time and memory, because the execution runtime process will be so streamlined.

Re:A first look at WebAssembly performance by TeMPOraL on Thursday February 09, 2017 @07:52AM (#13606528)
> Edit: Additionally, browsers will finally consume less power, CPU time and memory, because the execution runtime process will be so streamlined.

Don't worry, the software industry (and adtech) will find new cool ways to bloat the websites so that their resource usage will be back to usual high, while offered features stay more-less the same. That's pretty much how desktop, mobile and web all have been evolving so far.

Re:A first look at WebAssembly performance by majewsky on Thursday February 09, 2017 @08:25AM (#13606705)
This can also be seen the other way around. Given the speed at which websites pile on unnecessary shit, just imagine how websites would perform if browser vendors weren't busy optimizing all day long.
Re:A first look at WebAssembly performance by TeMPOraL on Thursday February 09, 2017 @08:46AM (#13606825)
That only matters if browser vendors stay ahead of the bloat curve (which I'm not so sure). Otherwise, one could say that for given performance point of the system (hardware platform + browser), there's a set level of bloat software sticks at, making the perceived performance constant.
Re:A first look at WebAssembly performance by Klathmon on Thursday February 09, 2017 @01:47PM (#13609628)
That's not really true, as JS engines will already compile things with the assumption that the types won't change and "bail out" if they do.

So if you can "hint" to the JIT that a variable is an integer, and it will stay an integer, then it will not only "unbox" it and treat it as an integer, it will compile the code very similar to how a static language would.

In asm.js, this is done by using little "tricks" of JS to hint to the compiler that something is (for example) an integer by appending `|0` to it.

So there really shouldn't be any major difference between "static language -> webasm" and "JS -> webasm" if the JS is written with performance in mind.

In practice you'll probably see greater performance from a static language simply because you "can't" violate those rules so there doesn't need to be really any "guarding" or checking, but you aren't looking at anything like a magnitude speed increase here, it'd be incremental in most cases.

Re:A first look at WebAssembly performance by flukus on Thursday February 09, 2017 @06:16PM (#13611943)
> That's not really true, as JS engines will already compile things with the assumption that the types won't change and "bail out" if they do.

Which makes for some great benchmarks but poor real world results.

Re:A first look at WebAssembly performance by Klathmon on Friday February 10, 2017 @07:12AM (#13614826)
It actually works suprisingly well.

After all, no JS engine out there would really tune their engines to benefit benchmarks at the expense of real-world performance.

Even with all the dynamic ability that something like JS gives you, most devs still create an object to store stuff, then don't change it. That means that an aggressive policy of "compile it as it is, and bail if it changes" ends up working much more often than it doesn't.

And in the cases where it doesn't, falling back to the "compile it dynamically" isn't going to be any slower than if they did that first, so it's basically a free optimization (as long as the compilation doesn't take that long).

Re:A first look at WebAssembly performance by hacker_9 on Thursday February 09, 2017 @04:14PM (#13611051)
Integers are hardly the worry. Any custom types the user makes are the problem.
Re:A first look at WebAssembly performance by Klathmon on Thursday February 09, 2017 @05:25PM (#13611605)
Integers are the worry.

the JIT being able to say "This here is an int, which means that this function takes an in and returns an int always, i'm going to compile it that way" means that now that function is "C-Speed".

If your program were filled with functions similar to that where the compiler is easily able to optimize the shit out of it, then it will run suprisingly close to "C-Speed".

Custom types (which I took to mean different data storage formats) aren't really something that the compiler can help with (any compiler). If you use a hashmap, you've got a hashmap, if you use a doubly-linked-list you've got a doubly-linked-list. C or JS iterating over an entire hashmap is going to be slower than iterating over memory addresses.

But luckily JS has stuff like TypedArrays which are basically C arrays with bounds checking.

And if you loop over it in a way that the compiler can determine you won't go out of bounds (say, with a simple for loop that runs while x < arr.length), you've got memory access at C speeds.

So you "can" (technically, on paper) make a JS program that would run at C speeds in most cases, but at the end of the day some part of your stack is going to begin using the dynamic parts of the language, and then you get the big speed roadblocks again. (by the way, the above is basically what ASM.js is, a well curated subset of JS which doesn't allow anything dynamic so that the JIT can compile it to run at "C speeds")

The benefits of a static language aren't in what they allow, but what they don't. Tying your hands and saying "No, you can't make an array of half strings and half integers" lets the compiler be simpler and not have to worry about those "edge cases", which means that it can focus on the "fast path" more. (in practice this almost always shows up as a faster language because JITs aren't perfect, so they can get confused by code that could technically be compiled more optimally but won't because the JIT can't identify it)

It's also why adding optional static typing to a language won't make it faster on it's own (after all, the JIT already knows what types variables are at calling time, telling it that again won't solve anything...)

Re:A first look at WebAssembly performance by hacker_9 on Friday February 10, 2017 @06:41AM (#13614701)
I don't think you are getting it. Here is a custom type in C#:

  public class CustomType
  {
      public int A;
      public int B;
      public CustomType2 C;
  }
At runtime this will mean any instance of this type is 32bit * 3 = 96 bits, plus the size of any metadata. Any code that accesses an instance member such as 'customType.B' will simply need to deref the address of customType, then add 32bits, and then deref the address of 'B' to get straight to the value.

Now let's do the same in JS:

  var list = [];
  for (i = 0; i < userSpecifiedLength; i++)
  {
      var customType = {};
      customType.A = i;
      customType.B = i * 10;
      if (i % 2 == 0)
          customType.C = { }
      list.push(customType);
  }
Perfectly normal dynamic JS code, but now at runtime the JS engine has no idea what 'customType' could possibly be, until is has attempted some sort of static analysis at runtime to figure out the fields. Additionally 'C' is optional, and whereas in C# that mean it may be null, in JS that means it could be undefined too.

There is also no guarantee that 'customType' is left as is and more fields aren't added to it later. All this leads to having to use dictionaries to store the information, which then require hash lookups every time you access a member. Fast, but not remotely near as fast as the C# runtime who has already mapped everything to an address.

Re:A first look at WebAssembly performance by Klathmon on Friday February 10, 2017 @07:05AM (#13614792)
That's almost the exact scenario I am talking about.

Your custom type there is perfect in JS. The JIT will VERY quickly determine that i is always an integer (actually before the code is first run it will have figured it out), and will "unbox" that to treat it as such (and not a JS "number" type). Objects in JS have a "hidden class" where they can be stamped out literally just like the C# example, so the JIT will be working with the exact same thing. A memory-mapped custom type.

Read up on "Hidden classes" [0] which can give you some insight into how it works. Basically as long as you treat a JS object like you'd treat that C# "custom type" (don't dynamically add or remove properties, stick to one type per property), it will instantly treat it identically to how C# would treat it until it changes (at which point it bails out and tries again, and if that happens too much, it will then default back to fully-dynamic).

But even if that weren't the case, you could still write your own data storage in JS that works like that. You could do something like this:

    const customType = new Uint32Array(3)
    const A = customType[0]
    const B = customType[1]
    const C = customType[2]
That storage will not only be typed, but will also have LESS overhead than the C# example, at the expense of clarity (after all, that's basically a C array there). This is basically how asm.js works, and what the code looks like when you compile C code into JS. Obviously you don't want to do that in most cases, but if the JS engine is your bottleneck and your data storage is causing slowness, then it might help.

JITs have come a LONG way in the past 5-10 years. It's pretty incredible what they can do, and it's actually not that hard any more to make smaller functions that can run at C speeds in V8 and SpiderMonkey.

[0] https://github.com/v8/v8/wiki/Design%20Elements

Re:A first look at WebAssembly performance by pcwalton on Thursday February 09, 2017 @12:35PM (#13608871)
> Nope, a static language will execute faster than a dynamic language, because the runtime knows precisely what type everything is and how much space to allocate.

asm.js is effectively a static language.

Re:A first look at WebAssembly performance by fmap on Thursday February 09, 2017 @06:08AM (#13606085)
JavaScript is JIT compiled, it has to be parsed, typechecked, interpreted and eventually compiled. WebAssembly is parsed and then translated to machine code (with a much simpler compilation pipeline).

Typical JavaScript VMs have a lot of fast paths for small scripts which also benefits small benchmarks like this. For more realistic workloads, parsing and compiling takes a significant amount of time and you could skip (almost) all of it by precompiling to WebAssembly (not at the moment, since you can't generate JavaScript objects from WebAssembly yet, but that'll happen eventually).

JavaScript in particular also has the problem that its semantics is an utterly horrifying mess... This forces the generated code to be very conservative and include a lot of dynamic checks and escape hatches to the interpreter. If anything, the situation is worse than with Lua, and let me remind you that LuaJIT doesn't actually compile said "escape hatches" because of code size. There are just that many of them.

Re:A first look at WebAssembly performance by crocodileJS on Thursday February 09, 2017 @05:29AM (#13605931)
Javascript doesn't have the same type information as WASM, also it lacks a native 64-bit integer. The JIT can do some type inference to use integers internally in some cases, but it's not optimal.

Predicting what sort of Javascript turns into what kind of native code on different JIT implementations is far from simple, too.

Even if in theory, an equivalent result should be possible in some cases, it's unrealistic to expect that in practice.

Re:A first look at WebAssembly performance by exDM69 on Thursday February 09, 2017 @10:16AM (#13607465)
> WebAssembly is all about the size of the binary and parsing overhead.

I don't think this is a good assessment.

WebAssembly needs to pass through a complete compiler backend before it can be executed.

WASM needs to be parsed, an in-memory representation is produced (probably LLVM IR), data flow and control flow graphs generated, a whole bunch of optimizations take place after which normal instruction selection, scheduling and register allocation and assembly take place.

This task is comparable in complexity to a JavaScript interpreter with a JIT compiler. However, JavaScript engines have optimized for a fast startup where the interpreter quickly starts running the program (while JIT'ing and optimizing in the background).

WASM has (or should have) two motivators: enabling near-native performance and allowing other languages to be compiled and executed in a browser. Based on this article, there's still a long way to go with performance. Most browser APIs are not accessible from WASM without some wrappers, so there's still work to be done before other languages become a viable replacement for JS.

Re:A first look at WebAssembly performance by bzbarsky on Thursday February 09, 2017 @03:06PM (#13610412)
> I don't think this is a good assessment.

It's not so much an assessment as one of the main stated goals of the project. The initial point of WebAssembly is to do what asm.js does but with a smaller on-the-wire size and much less processing overhead to get from the on-the-wire format to executable code. And more cross-vendor buy-in, so the results are more reliable.

> an in-memory representation is produced (probably LLVM IR),

It's not LLVM IR in either Firefox or Chrome, fwiw. In the case of Firefox, it's the IR that Ion (the "fastest" tier of the JIT) uses. I expect this to be a pretty common approach across browsers, actually; it lets you leverage your existing code generation infrastructure.

Safari actually tried using using LLVM for this sort of thing. They stopped. See https://webkit.org/blog/5852/introducing-the-b3-jit-compiler... for details.

> This task is comparable in complexity to a JavaScript interpreter with a JIT compiler.

Not really. Once you've got the IR you just use your existing codepaths for it; the IR generation from webasm is a much simpler task than IR generation from JS, complete with runtime instrumentation and whatnot.

Re:A first look at WebAssembly performance by hajile on Thursday February 09, 2017 @10:29AM (#13607557)
> I, for one, hope that WebAssembly will enable, say, Lua as a first class citizen on the web.

I can think of several languages I'd like to use on the web, but never really considered Lua.

I'm curious. Why Lua?

Re:A first look at WebAssembly performance by rch on Thursday February 09, 2017 @11:22AM (#13608020)
Apart from general fitness for embedding and extending, I like the versatility of Lua tables:

https://www.lua.org/pil/3.6.html

In particular, to initialize a table to be used as a record:

    a = {x=0, y=0}
which is equivalent to:

    a = {}; a.x=0; a.y=0
and:

    a.x = nil -- removes field "x"
But I think Guido's right about 0-based indexing:

http://python-history.blogspot.com/2013/10/why-python-uses-0...

Re:A first look at WebAssembly performance by strainer on Thursday February 09, 2017 @06:28PM (#13612028)
local a = {x=0,y=0} --lua table definition

is very similar to

var a ={x:0,y:0} //javascript object definition

Lua is great but that 1-based indexing is very unfortunate - works fine in itself but clashes badly with the norm.

Re:A first look at WebAssembly performance by Derbasti on Friday February 10, 2017 @02:24AM (#13613804)
Most popular dynamic programming languages are well-loved because they have huge standard libraries, which can largely not be ported to a browser sandbox. This is why I don't see how, say, Python or Ruby would be good sources of WebAssembly.

Lua, on the other hand, is a tiny language. It is remarkably well-designed, with a very simple type system, a very simple syntax, but nevertheless, Lua is extremely flexible.

I have spent a few years with Lue, and I have come to admire it, for it feels as flexible as Ruby, but at the same time more consistent than Python, and faster and simpler than either of those. And, needless to say, none of the inconsistencies of JavaScript.

Lua's stated goal is embeddability. The whole language including the parser and the standard library fit in a few hundred Kb. The bytecode only has a handful of very simple instructions. The source code is exceedingly well-structured and easy to understand.

I think Lua could be a very simple drop-in replacement for JavaScript, doing exactly the same thing that JS does today, but using a much nicer programming language. And it already comes with an object system, modules, and a string manipulation library.

I like Lua.

Re:A first look at WebAssembly performance by singularity2001 on Thursday February 09, 2017 @04:53AM (#13605782)
>> "but if they are possible with WebAssembly, they are also be possible with plain JavaScript"

only with asm.js not with 'plain' JavaScript

EDIT: sorry I completely missed the content of the OP! Wow

Re:A first look at WebAssembly performance by rnikhil275 on Thursday February 09, 2017 @04:50AM (#13605766)
Lua is already on the web. Check out the Sailor MVC Framework.
Re:A first look at WebAssembly performance by etiene on Thursday February 09, 2017 @05:05AM (#13605831)
Sailor author here. They probably mean on the front-end! :) For that we have Starlight (http://starlight.paulcuth.me.uk), which I use on Sailor as well. Very excited for the day we can run Lua natively on the browser!
Re:A first look at WebAssembly performance by rnikhil275 on Thursday February 09, 2017 @08:38AM (#13606776)
Yes. You are correct. I totally misunderstood the context.