🕌

Kotlin/Wasm をブラウザで実行し、JavaScript と比較してみた

2025/03/30に公開

はじめに

WebAssembly(略称:Wasm)は、ブラウザでの高速実行を可能にするバイナリフォーマットです。本記事では、Kotlin/Wasmを使ってブラウザで実行し従来のJavaScriptとのパフォーマンスを比較してみたので、その結果をまとめてみました。

Wasm の簡単な概要

Wasm の特徴は以下です。

  • Webブラウザ上でプログラムを高速実行するためのバイナリフォーマット。従来のJavaScriptよりも高速に動作することが期待できる
  • さまざまな言語からコンパイル可能。2025年3月時点では、Rust が最も使われている
  • 主要ブラウザ(Chrome、Edge、Safari、Firefox)で対応
  • Google Meet や Figma などの高度な計算処理を要するWebサービスで採用されている

Kotlin/Wasmについて

  • 「Kotlin/Wasm」という名称。Kotlin コードから WebAssembly を生成するためのプラットフォーム
  • Kotlin 開発元の JetBrains によって、Kotlin Multiplatform の一環として提供
  • 2025年3月時点ではまだアルファ版の段階

実際のパフォーマンス比較:フィボナッチ数列計算

Kotlin/Wasm と JavaScript のパフォーマンス比較のため、フィボナッチ数列の計算を例に検証してみました。

計算方法

  • 再帰関数を使ったフィボナッチ数列の計算(計算量:O(2^n))
  • 40項目の計算には約1兆回の計算が必要
  • 検証目的のため、メモ化などの最適化は使わない

実装方法

JetBrains が提供しているサンプルを参考に実装しました。
https://github.com/Kotlin/kotlin-wasm-nodejs-template

JavaScript実装

function fibonacciJS(n) {
  if (n <= 1) {
    // nが0または1の場合は、nを返す
    return n;
  } else {
    // nが2以上の場合は、再帰的に計算する
    return fibonacciJS(n - 1) + fibonacciJS(n - 2);
  }
}

Kotlin/Wasm 実装

@WasmExport
fun fibonacciKotlin(n: Int): Int {
  return if (n <= 1) {
    // nが0または1の場合は、nを返す
    n
  } else {
    // nが2以上の場合は、再帰的に計算する
    fibonacciKotlin(n - 1) + fibonacciKotlin(n - 2)
  }
}

ビルド設定(build.gradle.kts)

kotlin {
  // JavaScript と相互互換するために、wasmJs ターゲットを追加
  wasmJs {
    binaries.executable()
    nodejs()
  }
}

ビルド実行

./gradlew wasmJsNodeRun

検証時にはビルドコマンドは Failed となってしまっていましたが、.wasm ファイルなどのビルド生成物は生成されます。

JavaScript から Wasm の呼び出し

let fibonacciKotlin;

// Wasmモジュールのインポートを動的に行う
import('../kotlin-wasm-fibonacci-example-wasm-js.mjs')
  .then(module => {
    fibonacciKotlin = module.fibonacciKotlin;
    console.log('Wasmモジュールが正常にインポートされました。');
  })
  .catch(error => {
    console.error('Wasmモジュールのインポートに失敗しました:', error);
  });

function generateFibonacciWasm(n) {
  const sequence = [];
  for (let i = 0; i < n; i++) {
    sequence.push(fibonacciKotlin(i));
  }
  return sequence;
}

実際の検証結果

検証の結果、以下のような実行時間が計測できました。

入力値(n) 計算量 Kotlin/Wasm実行時間 JavaScript実行時間 速度比
30 10億回 10ms 22ms 2.2倍速い
35 340億回 58ms 94ms 1.6倍速い
40 1兆回 664ms 958ms 1.4倍速い
45 35兆回 7,453ms 10,627ms 1.4倍速い

入力値が小さい場合(n = 30)では Kotlin/Wasm が約2.2倍速く、入力値が大きくなるにつれて差は縮まるものの、最も重い計算(n = 45)でも約1.4倍のパフォーマンス向上が確認できました。

実際に動くデモ

実際に作成した Kotlin/Wasm と JavaScript の比較デモは以下のリンクから試すことができます。
https://wasm-fibonacci-example.s3.ap-northeast-1.amazonaws.com/kotlin/index.html

終わりに

Wasmはまだまだ発展段階ですが、やはりパフォーマンス向上には期待できるため、今後普及していく可能性を秘めた技術かと思います。
トレンドとしては Rust + Wasm ではあるものの、 Kotlin/Wasm も成熟して選択肢の1つとなり得たら面白いですね。

Discussion