Vyacheslav Egorov

mrale.ph · Personal blog · on HN since 2012

Vyacheslav Egorov, a compiler engineer who worked on V8 and the Dart VM, writes about JavaScript engine optimization and benchmarking.

What HN saysHN commenters say he reliably produces high-quality V8 material, call the site full of hidden goodies, and recommend it for learning how V8 optimizes code.
102HN people shared it
59linked it in comments
58stories submitted
2.0Kstory points
6 months agolast shared
2012people per year2026

Most-shared posts

  1. 1
    Maybe you don't need Rust and WASM to speed up your JS
    17 people · 750 points · first shared 2018 · 181 comments on HN
  2. 2
    What's up with monomorphism?
    13 people · 70 points · first shared 2015 · 10 comments on HN
  3. 3
    Why Asm.js Bothers Me
    11 people · 274 points · first shared 2013 · 163 comments on HN
  4. 4
    Homepage
    8 people · first shared 2013
  5. 5
    Introduction to Dart VM
    7 people · 114 points · first shared 2019 · 27 comments on HN
  6. 6
    IRHydra²
    7 people · 12 points · first shared 2014 · discussion on HN
  7. 7
    Grokking V8 closures (2012)
    6 people · 35 points · first shared 2012 · 3 comments on HN
  8. 8
    Adventures in the land of substrings and RegExps
    5 people · 137 points · first shared 2016 · 12 comments on HN
  9. 9
    Benchmarking JS
    4 people · 147 points · first shared 2015 · 31 comments on HN
  10. 10
    Browser as an Interactive Disassembler (2015)
    4 people · 78 points · first shared 2015 · 4 comments on HN
  11. 11
    The Black Cat of Microbenchmarks
    4 people · 52 points · first shared 2015 · 5 comments on HN
  12. 12
    Grinch about the array.length caching
    4 people · 20 points · first shared 2014 · 5 comments on HN
  13. 13
    The trap of the performance sweet spot (2011)
    4 people · 3 points · first shared 2013 · discussion on HN
  14. 14
    New Fn() vs. Object.create(P)
    3 people · 67 points · first shared 2015 · 20 comments on HN
  15. 15
    Shaky diagramming (2012)
    3 people · 13 points · first shared 2015 · 1 comments on HN

What HN people wrote when they linked it

jwmerrill · 2016-07-05
There's some information about how to collect (and visualize!) JS compilation artifacts in the IRHydra documentation [1]. It's v8 specific, though. The other writings on that site are worth studying if you want to learn more about how v8 optimizes code [2]. [1] http://mrale.ph/irhydra/2/ [2] http://mrale.ph
masklinn · 2015-11-25
> This is so important: [benchmark] As any follower of @mraleph (http://mrale.ph / https://twitter.com/mraleph) is aware, it's very easy to benchmark the wrong thing (or benchmark more or less nothing), or to write an isolated benchmark which doesn't reflect real-world use.
inglor · 2015-05-13
Can always trust Vyacheslav Egorov to pump out super high quality stuff about v8. His blog http://mrale.ph/ is full of hidden goodies like Object.create vs function constructor [1] and hidden classes vs jsperf [2]. Lots of good stuff on his SO too. It'd be great if he (hi if you're reading this btw!) could write a bit about TF and the changes being made to v8 internally from an overview point of view. [1] http://mrale.ph/blog/2014/07/30/constructor-vs-objectcreate.html [2] http://mrale.ph/blog/2013/08/14/hidden-classes-vs-jsperf.html
fridek · 2013-08-19
To be fair - I've never seen such docs for SpiderMonkey. I may have just failed at finding them though. Keeping up-to date documentation of compiler is a horrible job. I think it's good enough that V8 may be built as standalone binary with really extraordinary debug options and tools. At the same time, I'd love to see more talks like http://www.youtube.com/watch?v=FrufJFBSoQY There are also guys who write about V8 from time to time (http://mrale.ph/ http://floitsch.blogspot.com/ http://wingolog.org/tags/v8) but this is needle-in-a-haystack type of learning.
emmanueloga_ · 2020-04-27
humble opinion: N years of using any language won't make you an expert. There's knowledge about how to express certain patterns in a given language, more like an application design expertise. There's knowledge and familiarity with the APIs. And then there's the deep language knowledge, the one that pretty much only someone implementing a language VM, parser, compiler and other tools may acquire with time. Also, there are a lot of specifics about every particular JS implementation. Also, Dunning–Kruger :-) On the internals of VMs, https://mrale.ph/ has a lot of blog posts on internals/optimizations on V8. https://www.wingolog.org/tags/javascript also has deep JS articles very freqently.
mraleph · 2019-04-25
Dart VM is written primarily in C++. There is bytecode, but the story here is kinda complicated - there are actually 2 different versions: one is called DBC and is used during development of Flutter applications on iOS, there is another called KBC - that one is more like a classical bytecode, it is currently in development. > And is there a place where more details are available? You can get some high level information at https://mrale.ph/dartvm Let me know if you want to know something special.
vmsp · 2019-01-22
If you're interested in the Dart VM, I also recommend taking a look at Vyacheslav Egorov's Introduction to Dart VM (https://mrale.ph/dartvm/).
fenomas · 2017-08-21
I don't think there are any really solid approaches here except to use IRHydra [0], which lets you decompile v8's optimized version of a function into an assembly-like representation. But I'm pretty skeptical of whether anyone but v8 engineers can really make use of it. I think the only workable approach is what you're doing - have an approximate idea of how the compiler works and make intelligent guesses about what will help. But when you're tuning at the level where changing the order of if statements makes a difference, you're at the level where next month's update may reverse your fix, so in a lot of cases it'll be questionable whether it's worth the effort. [0] IRHydra - http://mrale.ph/irhydra/2/
alexdima · 2017-02-08
When we started the project, we did write tokenizers by hand. I mention that in the blog post. You can write some very fast tokenizers by hand, even in JavaScript. Of course they won't be as fast as hand written tokenizers in C, but you'd be surprised how well the code of a hand written tokenizer in JavaScript can be optimized by a JS engine, at least I was :). IR Hydra 2 is a great tool to visualise v8's IR representation of JS code [1]. It is a shame it is not built into the Chrome Dev Tools. In the end, we simply could not write tokenizers for all languages by hand. And our users wanted to take their themes with them when switching to VS Code. That's why we added support for TM grammars and TM themes, and in hindsight I still consider it to be a very smart decision. [1] http://mrale.ph/irhydra/2/
EdSharkey · 2016-12-13
If you write your javascript in a way that is easy for V8 to JIT, then I think you'll benefit most from progressive enhancements made in the underlying engine. There's a lot of talks and articles on V8 performance, for example: http://mrale.ph/v8/resources.html Surprisingly, very boring, predictably shaped prototypey classes written in the "hidden classes" style they prescribe will JIT compile amazingly well. I think a lot of the fancy uses of JavaScript to roll types with mixins and traits or simply to sidestep needing the 'new' keyword to instantiate objects miss out on lots of performance benefits on V8. Honestly, where does all the hate for 'new' come from? Prototypey classes work fine once you understand how to roll them/extend them, and 'new' is a real keyword in the language, what's to hate?
boulos · 2015-09-26
It's too bad his README.md doesn't have some screenshots. Luckily, his site for IRHydra2 has a screencast you can scrub through (http://mrale.ph/irhydra/2/) to get at least a sense of what it looks like. This tooltip here was pretty fantastic (https://www.youtube.com/watch?t=725&v=pycQWDuCBN8), seems like a great project!
jeresig · 2013-04-03
If others have not read the parent's blog post on Asm.js, I highly recommend it: http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html I also largely agree with Jason's comment on that post: http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html#comment-8454… I see no reason why these efforts can't run in parallel - as certain optimizations are needed to improve execution performance standardize them and expose them to user-written JavaScript. I'll say that I would be totally happy if Asm.js was nothing more than a line drawn in the sand that all the browser vendors then aspired to match with normal JavaScript. Knowing what is theoretically possible in a browser is a huge motivator (as was seen in the last browser JS performance war of 2008/2009).
apaprocki · 2012-12-16
http://mrale.ph/blog/2012/12/15/microbenchmarks-fairy-tale.html Slava always has great live presentations and has a great blog.
testdelacc1 · 2026-01-08
A benchmark of adding numbers doesn’t tell you how it performs on real world websites and codebases. I wouldn’t be surprised if JavaScript was still very competitive, simply because of how good V8 is, but I don’t think we can conclude anything from your benchmark. Of course it is always possible to write highly optimised code. But that’s not what people actually do, because of time, skill and maintenance constraints. Here’s a case study: in 2018 Mozilla ported some code from JS to Rust + WASM and got a 6x speed up [1]. An expert in V8 responded to this with highly optimised JavaScript, saying Maybe you don't need Rust and WASM to speed up your JS [2]. Both articles are worth reading! But it is worth remembering that it’s a lot quicker and easier to write the code in #1 than #2 and it is easier to maintain as well. [1] - https://hacks.mozilla.org/2018/01/oxidizing-source-maps-with-rust-and-… [2] - https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…
maga · 2022-02-01
> You’re still missing much the point of the article: WASM isn’t for the browser only. WASI, for example, is a full environment you can run stuff in without any such interoperability cost. Of course, but we are not arguing about the point of the article, I'm contesting the exact claim that "WebAssembly is almost always faster than JavaScript". Admittedly, not because it's such a big mistake on the author's part, but because I'm a bit irate with the usual flow of discussions about WebAssembly here on HN that take this claim for granted and regurgitate it incessantly. This is not the case for the mentioned reasons: data copying overhead and JS itself being compiled by JIT resulting in pretty performant code if well-optimized. Also, the comparison to JS only makes sense when we are talking about running both in the JS engine, not against a dedicated WASM runtime, otherwise it would be tantamount to arguing that Java is not faster than JS. By the way, if someone really wants to dig into the issue I recommend an article from one of the V8 authors where he dissects one such WASN success story: https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…
twotwotwo · 2017-09-03
Commented this on the blog; cross-posting here: V8 turns out to have a ton of internal string representations. They don’t affect semantics (the general point that JS string functions think in UTF-16 is valid) but they’re interesting. V8 apparently stores all-ASCII strings as ASCII, so stuff like HTML tag names or base64 blobs doesn’t double in size. Like Go, V8 lets you take a substring as a pointer into the larger string; the internal class is called SlicedString, but from JS-land you don’t see anything different from a string literal. As in Go, keeping a short substring of a long parent string keeps the whole parent ‘alive’ across GCs so sometimes folks will be surprised all those bytes are still allocated. Unlike Go, V8 has a ConsString type, so concatenating strings sometimes doesn’t really immediately copy the underlying bytes anywhere. Building a string with a loop that runs str += newPiece probably goes faster than expected because of this. [It turns out it flattens the string the next time you index into it, or at least used to, which has some perf implications of its own: https://gist.github.com/mraleph/3397008] That’s mostly from this post by a member of the Dart team http://mrale.ph/blog/2016/11/23/making-less-dart-faster.html ; his blog has a lot of interesting stuff about how these fine-tuned language implementations really work. Kind of amazing the lengths V8 (and other JS engine) teams went to to make the code they saw in the wild work well.
nybblet · 2017-08-22
Not what I said. I said to avoid /hand-optimizing/ code. Trying to write performant code is good. Some examples of advice on that front: - use an appropriate algorithm, and make sure the logic is free of bugs. For example, accidental out-of-bounds array accesses can really hurt performance. - avoid needless computations. Don't do something (complex) twice if doing it once is enough. If this sounds like "use common sense/generally good design principles", that's because it is (and hence the agreement with many of parent post's points that are simply and straightforwardly good design principles). Let's take the example of "remove function calls". It's true that each call costs a few instructions, but unless the function you're calling is tiny, that overhead won't be measurable. If it makes sense for readability/maintainability/testability to split your code into functions, then by all means do it! Another example is the "trick" to write "for (var i = 0, len = array.length; i < len; i++)" instead of the simpler "for (var i = 0; i < array.length; i++)". As http://mrale.ph/blog/2014/12/24/array-length-caching.html (from the original V8 team) explains in great detail, what seems like a no-brainer can actually do the opposite of what you'd expect --- and at the same time, won't make any difference whatsoever in most real code (i.e. aside from microbenchmarks). Yet another example is https://www.youtube.com/watch?v=UJPdhx5zTaw. You can spend all day on it, but at the end of the…
floitsch · 2014-04-26
In JavaScript every object is basically a hashtable. In order to get acceptable performance JS engines build type descriptions ("hidden classes" or sometimes just "maps") behind your back. That is, if you create a JS object (hashtable) with fields `x` and `y` it will create a hidden class with those two fields. This way it can access the fields efficiently. See http://mrale.ph for much more information on JS engines. These hidden classes are built on the fly: say you add `x` to a instance to get an object with a configuration that was never seen before. In that case, the engine creates a new description with that new field and remembers the transition (so that further objects with similar configurations can reuse the same hidden class). Keeping track of these hidden classes takes time and space. If you actually use the JS object as a hashtable, then there will be lots of unnecessary hidden classes, that will never be used again. However, there is a trick to tell the engine that an object is actually a hashtable (and shouldn't be optimized as if it was an instance of a class): when deleting a field from an object v8 (and probably all other engines) assume that the object is used as a hashtable and don't create these hidden classes anymore. Dart2js uses this trick to avoid this cost some important big hashtables (`B`, `C`, ...).
mythz · 2013-06-19
Only Firefox uses a separate special interpreter (Odin Monkey) for asm.js - Chrome's asm.js improvements come from optimizing the same V8 JS pipeline. Having a separate compilation pipeline can be viewed as a disadvantage since any optimizations for speeding up asm.js doesn't improve JS performance: http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html > It will still not be comparable to asm.js, because asm.js runs in all browsers without the site author having to do anything Dart web apps will continue to run in all browsers just as it runs today through Dart2JS, it even has great source maps support which lets you debug native Dart code even though it's running transpiled JS. There's nothing special the "author" would have to do, it already exists as part of the project template, e.g. if the browser has a Dart VM it will run the Dart code natively, otherwise it will run the Dart2JS version. Since some Dart benchmarks http://www.dartlang.org/performance/ show Dart2JS outperforming handwritten JS in V8 even with the overhead of different semantics, I'm assuming that Dart2JS compiles to efficient JS that developers wouldn't write. > because asm.js runs in all browsers runs is a technically interesting term, there are some asm.js demos that you would not attempt to run without asm.js specific optimizations (i.e. not Firefox) since it would be unusably slow. This is visible in the Epic Citadel http://www.unrealengine.com/html5/ flagship asm.js demo where it needs a…
just2n · 2013-05-02
I understand that. Take a read of this: http://mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html. I have a lot of respect for Egorov, and I agree with his views on this matter quite entirely. The sole benefit of embedding a bytecode in a language is that you get the side effect that it can run anywhere that language runs. But in general, this implies performance penalties, especially when the language is relatively slow to begin with. But in this case, this demo is made usable (ie: the impressive part) by writing a compiler specifically for the bytecode itself. So it works well in spite of the fact that it's a bytecode embedded in JS, not because of it. The really cool things about this demo are precisely 2 things: 1. asm.js makes running C++ code that would render to OpenGL in the browser a possibility, and with relatively good performance. Kudos to Mozilla. 2. It runs on browsers that don't know about asm.js, but it's effectively an emulated machine, and it's slow. I just take issue with calling this an example of what JavaScript/HTML5 can do. I think seeing an application written in JS using WebGL or Canvas as something much more impressive, and there are Q3 renderers that are natively JS that run with amazing performance in the browser. This is just dressing up the fact that turing completeness is a thing and calling attention to it. The real thing to get from this demo is that there are enormous benefits to having a bytecode for the web over trying to optimize a…
codethief · 2023-09-10
> most of the time Looking at the reference[0] given at the very end of the document, wouldn't the word "sometimes" be more appropriate? [0]: https://mrale.ph/blog/2016/11/23/making-less-dart-faster.html
rileyphone · 2022-11-09
Based on https://mrale.ph/dartvm/, it looks like there are two way Dart gets optimized now - either through a JIT like V8, or AOT compilation with a fallback for the methods that can't be devirtualized. The JIT still performs better, but the AOT code starts up faster. The next challenge is to combine them and eliminate cold starts with dynamic optimization.
cesarb · 2022-07-15
To save some searching, the three referenced articles seem to be: - Oxidising Source Maps with Rust and WebAssembly: https://hacks.mozilla.org/2018/01/oxidizing-source-maps-with-rust-and-… - Maybe you don’t need Rust and WASM to speed up JS: https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-… - Speed Without Wizardry: https://fitzgeraldnick.com/2018/02/26/speed-without-wizardry.html
davidmurdoch · 2021-03-02
> involves performance [...] problems Except when it solves them! https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…
illuminated · 2020-06-09
In theory, you can write another language frontend for the Dart VM, but it isn't being utilized a lot as I can tell. Here's a year and a half old page describing the Dart VM's internals: https://mrale.ph/dartvm/ Also, here are two examples of different frontend add-ons for the Dart VM, although outdated: https://github.com/thosakwe/bullseye and https://github.com/jvasileff/ceylon-dart
spion · 2020-02-15
An interesting blog post on how that might be done: https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…
mnutt · 2019-02-14
It isn't a rebuttal to this article, but I found this blog post about optimizing javascript to be really, really interesting: https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…
thoughtspile · 2018-09-24
(I don't know why we're doing it in English) For the more general tech (physics and stuff) — https://sly2m.livejournal.com/ https://sly2m.livejournal.com/tag/%D0%BD%D0%B0%20%D0%BF%D0%B0%D0%BB%D1… series especially recommended For programming, I enjoy https://igoradamenko.com/blog/ These seem mostly dead, but might come back: - https://medium.com/@kovchiy - https://medium.com/@xanf Here's a guy working on V8 who ocassinally posts / talks in Russian: https://mrale.ph/talks/
pygy_ · 2018-04-19
You can defeat inlining by using closures: function thunk(x){ return function() { x() } } const thunkFoo = thunk(foo) const thunkBar = thunk(bar) for(var i = 0; i < 10000; i++) { thunkFoo() thunkBar() } This is why the "Maybe you don't need Rust to speed up your JS" author was creating functions dynamically using `new Function()`. Maybe you cal get away with function call(x){ x() } for(var i = 0; i < 10000; i++) { call(foo) call(bar) } I didn't test the latter though, whereas the former is empirically slower if you call more than one thunk in your benckmark loop (a single thunk will have the call inlined). https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-…

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close