Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Tuesday, March 3, 2015

Improving V8's performance using the serializer/deserializer

V8 has long been using so-called snapshots to improve start-up time. By capturing a snapshot of a fresh V8 instance, initializing Javascript globals no longer require executing native scripts where they are defined, but simply deserializing the snapshot. A d8 shell built with snapshot starts within 15ms as opposed to 55ms without.

A minor sometimes overlooked detail is that the snapshot not only speeds up creating a V8 isolate via v8::Isolate::New, but also contexts created via v8::Context::New, as the snapshot is used as a template.

Recently, the serializer and deserializer implementing the start-up snapshot have been improved to support new features. In the following I want to give a brief introduction to two new embedder-facing APIs that - if used correctly - can improve performance significantly.

Tuesday, August 26, 2014

It's a little known fact that Firefox's Spidermonkey has switched to a new RegExp engine recently. They abandoned YARR, which they took from WebKit's JSC a few years ago, and replaced it with the high-performance Irregexp from Chrome's V8. Porting it to Spidermonkey certainly was a tremendous job. As a result, their benchmark score on Octane/regexp improved a lot. (Orange for Firefox/Spidermonkey, green for Chrome/V8)

But for some reason, it's still pretty far away from V8's score in that particular benchmark. Let's speculate on why this is the case.

Debugging promises in Chrome

With the upcoming Chrome 36, Javascript Promises as specified in the upcoming revision of the ES6 standard are going to be activated by default as part of V8. Right now, you can already try it in the Dev or Canary release channels.
While a very useful addition to the language, especially with regard to asynchronous programming, Promises are peculiar when it comes to debugging: it swallows exceptions by default.

Mongolian Vowel Separator

In ECMA-262 5.1, white space characters are defined in chapter 7.2 as following characters
\u0009 \u000B \u000C \u0020 \u00A0 \uFEFF
... and Other category "Zs", as defined for Unicode.
Well, that's simple, right? The Unicode database is available for download and easy parsing. Let's do this

Finding De Bruijn sequence to calculate Math.clz32.

As specified in the latest Javascript ES6 draft, Math.clz32 (formerly Number.prototype.clz) calculates the number of leading zeros to an 32-bit integer, and returns 32 for 0.
The simple implementation for this is therefore:
function clz_simple(x) {
  for (var i = 0; i < 33; i++) {
    if (x & 0x80000000) return i;
    x <<= 1;
  }
  return 32;
}
In the worst case, the loop is executed 33 times. A smarter implementation would use binary search.

Quake 3 in Javascript

This is pretty impressive. Even more impressive is the technology behind it.

Apparently, Quake 3 strictly separates game engine from game content. The latter are packaged as platform-independent bytecode and run in a virtual machine. That is, either interpreted, or, for more common platforms, compiled to machine code. The advantages are, among others, platform independence and sandboxing potentially unsafe game content.


The Javascript port includes a Javascript backend for that virtual machine: the bytecode is translated to Javascript, and the resulting Javascript source string is fed into eval, and run by the Javascript virtual machine inside the browser.

The performance is not bad, considering that we have a double-nested virtualization. The game runs very smoothly on my Chromebook Pixel.

Chromium blog post

Something from work:
V8 compiles optimized code in the background.

with scope, const and var.

Consider the following functions:

function foo() {
  var o = { a: 1 };
  with (o) {
    var a = 2;
  }
  return(o.a);


function bar() {
  var o = { a: 1 };
  with (o) {
    const a = 2;
  }
  return(o.a);
}

Eagle-eyed readers will have noticed that the only difference between the functions foo and bar is the variable declaration inside the with scope.

foo() returns 2.
bar() returns 1.