# raven

Published articles for raven.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## WebAssembly interpreter performance depends on the runtime, not just the code pattern

DevFeed: [WebAssembly interpreter performance depends on the runtime, not just the code pattern](<https://devfeed.tech/articles/the-value-of-a-performance-oracle-35035.md>)

Original publisher: [Read original article](<https://wingolog.org/archives/2026/04/07/the-value-of-a-performance-oracle>)

Author: Andy Wingo

Published: 2026-04-07T12:49:39Z

Content type: article

Language: en

Sources: [wingolog](<https://devfeed.tech/sources/wingolog.md>)

Topics: [Rust](<https://devfeed.tech/topics/rust.md>), [WebAssembly](<https://devfeed.tech/topics/web-assembly.md>), [Assembly](<https://devfeed.tech/topics/assembly.md>), [toolchain](<https://devfeed.tech/topics/toolchain.md>), [V8](<https://devfeed.tech/topics/v8.md>), [Chrome](<https://devfeed.tech/topics/chrome.md>), [Firefox](<https://devfeed.tech/topics/firefox.md>)

Tags: [assembler](<https://devfeed.tech/tags/assembler.md>), [assembly](<https://devfeed.tech/tags/assembly.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [firefox](<https://devfeed.tech/tags/firefox.md>), [oracles](<https://devfeed.tech/tags/oracles.md>), [performance](<https://devfeed.tech/tags/performance.md>), [performance-oracles](<https://devfeed.tech/tags/performance-oracles.md>), [raven](<https://devfeed.tech/tags/raven.md>), [rust](<https://devfeed.tech/tags/rust.md>), [tail-calls](<https://devfeed.tech/tags/tail-calls.md>), [toolchain](<https://devfeed.tech/tags/toolchain.md>), [wasm](<https://devfeed.tech/tags/wasm.md>), [wasmtime](<https://devfeed.tech/tags/wasmtime.md>), [wastrel](<https://devfeed.tech/tags/wastrel.md>), [webassembly](<https://devfeed.tech/tags/webassembly.md>)

### AI overview

The article revisits a comparison of switch-based and tail-calling bytecode interpreters. Its measurements confirm earlier native and Wasmtime results but report that Wastrel substantially reduces the apparent WebAssembly penalty, suggesting that the poor performance is runtime-specific rather than inherent to WebAssembly.

### Source excerpt

Over on his excellent blog, Matt Keeter posts some results from having ported a bytecode virtual machine to tail-calling style. He finds that his tail-calling interpreter written in Rust beats his switch-based interpreter, and even beats hand-coded assembly on some platforms. He also compares tail-calling versus switch-based interpreters on WebAssembly, and concludes that performance of tail-calling interpreters in Wasm is terrible: 1.2x slower on Firefox, 3.7x slower on Chrome, and 4.6x slower in wasmtime. I guess patterns which generate good assembly don't map well to the WASM stack machine, and the JITs aren't smart enough to lower it to optimal machine code. In this article, I would like to argue the opposite: patterns that generate good assembly map just fine to the Wasm stack machine, and the underperformance of V8, SpiderMonkey, and Wasmtime is an accident. some numbers I re-ran Matt's experiment locally on my x86-64 machine (AMD Ryzen Threadripper PRO 5955WX). I tested three toolchains: Compiled natively via cargo / rustc Compiled to WebAssembly, then run with Wasmtime Compiled to WebAssembly, then run with Wastrel For each of these toolchains, I tested Raven as implemented in Rust in both "switch-based" and "tail-calling" modes. Additionally, Matt has a Raven implementation written directly in assembly; I test this as well, for the native toolchain. All results use nightly/git toolchains from 7 April 2026. My results confirm Matt's for the native and wasmtime toolchains, but wastrel puts them in context: We can read this chart from left to right: a switch-based interpreter written in Rust is 1.5x slower than a tail-calling interpreter, and the tail-calling interpreter just about reaches the speed of hand-written assembler. (Testing on AArch64, Matt even sees the tail-calling interpreter beating his hand-written assembler.) Then moving to WebAssembly run using Wasmtime, we see that Wasmtime takes 4.3x as much time to run the switch-based interpreter, compare