SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Rust言語で作るWebバイナリファイル「WebAssembly」入門

Rustでわかる! WebAssemblyのメリット~処理速度の違いを、サンプルを作りながら体験しよう

Rust言語で作るWebバイナリファイル「WebAssembly」入門 第3回

  • このエントリーをはてなブックマークに追加

 本連載では、Webブラウザー上でJavaScriptとともに動作できるバイナリ形式のプログラムファイル「WebAssembly」を、Rustプログラミング言語で実装する方法を説明していきます。前回はRust言語の基礎を説明しました。今回はいよいよ、Rust言語でWebAssemblyを実装していきます。また実装したサンプルを利用して、WebAssemblyのメリットなどを説明します。

  • このエントリーをはてなブックマークに追加

はじめに

 本連載では、Webフロントエンド開発において注目されているバイナリ形式のプログラムファイルWebAssemblyを、Rustで実装して活用する方法を説明しています。初回記事ではWebAssemblyの背景およびRust開発環境の作成について、前回記事ではRust言語の基本的な言語仕様について説明しました。

 今回はこれまで説明した内容を利用して、実際にRust言語でWebAssemblyを実装していきます。簡単なサンプルを作りながら、実装の手順やWebAssemblyのメリットなどを説明します。

対象読者

  • 動的なWebページにさらなる速度を求める方
  • RustやWebAssemblyの概要を知りたいフロントエンドエンジニアの方
  • WebAssemblyを利用するメリットを実感したい方

必要な環境

 本記事のサンプルコードは、以下の環境で動作を確認しています。

  • Windows 10 64bit版
  • Microsoft Edge 100.0.1185.36
  • rustup 1.24.3
  • cargo 1.60.0
  • wasm-pack 0.10.2
  • Node.js v16.14.2 64bit版

 サンプルコードには、WebAssemblyをビルドするRustのプロジェクトと、ビルドしたWebAssemblyを利用してWebページを表示するプロジェクト(プロジェクト名の末尾が「-web」のもの)が含まれます。前者は「wasm-pack build」コマンドでビルドできます。後者を実行するには、WebAssemblyプロジェクトをビルドして生成した「pkg」フォルダーをサンプルのフォルダーにコピーした後、「npm install」コマンドでライブラリーをインストールします。その後「npm run start」コマンドを実行して、Webブラウザーで「http://localhost:8080/」を表示します。

繰り返し処理で円周率を計算するサンプル

 WebAssemblyと言えば、重い計算処理を高速で行うイメージを持つ人が多いのではないでしょうか。そこで本記事ではまず、図1に示す「ライプニッツの公式」で円周率を計算するサンプルを紹介します。この公式では、分数の加算処理を繰り返すことで、円周率を求められます。

図1 円周率を求めるライプニッツの公式

 なお、円周率を求める方法には、より計算効率や精度の高いものが存在しますが、本記事では比較的処理が単純で、かつ、計算量の多い例として本公式を使用していきます。

 ダウンロードできるサンプル(p001-calc-pi-web)を実行すると、図2の通り、円周率を計算してWebページのダイアログ(alert)で表示します。

図2 円周率を求めるサンプルの実行結果(p001-calc-pi-web)

 以下では図2のサンプルを、Rust/WebAssemblyで作っていきます。Rust/WebAssembly開発環境の作り方は、本連載の初回記事も参考にしてください。

 まず、ライプニッツの公式をRustで実装するプロジェクトを、リスト1のコマンドで生成します。

[リスト1]RustのWebAssemblyプロジェクトを生成するコマンド
cargo generate --git https://github.com/rustwasm/wasm-pack-template

 処理を実装するファイルは、生成されたプロジェクト内のsrc/lib.rsです。円周率を計算するライプニッツの公式は、Rustでリスト2の通り実装できます。

[リスト2]Rustで実装したライプニッツの公式(p001-calc-pi/src/lib.rs)
#[wasm_bindgen] // ...(1)
pub fn calc_pi(count: u64) -> f64 { // ...(2)
    let mut i = 1_u64; // ...(3)
    let mut value = 1.0_f64; // ...(4)
    while i <= count { // ...(5)
        let index = 2 * i - 1;
        value = value
            - 1.0 / ((2 * index + 1) as f64)
            + 1.0 / ((2 * (index + 1) + 1) as f64);
        i += 1;
    }
    return value * 4.0; // ...(6)
}

 (1)の#[wasm_bindgen]は、WebAssemblyの関数を呼び出すJavaScriptのメソッドを生成することを表す記述です。(2)で、u64(符号なし64ビット整数)の計算回数countを引数にとり、f64(64ビット浮動小数点数)で円周率を返却する関数calc_piを定義します。関数の中では、まず(3)でu64型の変数i、(4)でf64型の変数valueを定義します。「let mut」は変数が変更できることを表し、「1_u64」や「1.0_f64」は、変数の初期値と型を表します。(5)のwhileループでライプニッツの公式に基づいた処理を行い、計算された円周率を(6)で返却します。Rustの文法については、前回記事も参考にしてください。

 リスト2の実装後、リスト3のコマンドでWebAssemblyをビルドします。ビルド実行後、WebAssemblyと、それを呼び出すためのJavaScriptファイルなど一式が、プロジェクトのpkgフォルダーに生成されます。

[リスト3]WebAssemblyをビルドするコマンド
wasm-pack build

 次に、WebAssemblyを実行するWebページのプロジェクト(p001-calc-pi-web)を、リスト4のコマンドで生成します。

[リスト4]WebAssembly用のWebページプロジェクトを生成するコマンド
npm init wasm-app <プロジェクト名>

 生成されたプロジェクトのフォルダーに、WebAssemblyプロジェクトをビルドして生成されたpkgフォルダーをコピー後、package.jsonにリスト5の通り記述して、pkgフォルダーの内容をパッケージとしてJavaScriptから参照できるようにします。

[リスト5]WebAssemblyのパッケージを参照する記述(p001-calc-pi-web/package.json)
"dependencies": {
  "p001-calc-pi": "file:./pkg"
},

 Webページ表示時に実行されるindex.jsファイルに、WebAssemblyの円周率計算処理を呼び出す実装を、リスト6の通り行います。リスト5で記述したWebAssemblyのパッケージを(1)でインポートして、そのcalc_piメソッドを(2)で呼び出して円周率を計算します。calc_piメソッドの引数で利用しているBigIntは、JavaScriptで巨大な整数を表すオブジェクトで、Rustのリスト2(2)で指定した64ビット整数に対応するために利用します。

[リスト6]WebAssemblyを実行して円周率を計算する実装(p001-calc-pi-web/index.js)
// WASMをインポート ...(1)
import * as wasm from 'p001-calc-pi';
// WASMのcalc_piメソッドで円周率を計算 ...(2)
alert(wasm.calc_pi(BigInt(10000000)));

 ここまで実装後、「npm install」コマンドでライブラリーをインストールして「npm run start」コマンドで実行後、Webブラウザーで「http://localhost:8080/」を表示すると、図2の通り円周率を計算できます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
WebAssemblyとJavaScriptの処理速度の比較

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
Rust言語で作るWebバイナリファイル「WebAssembly」入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/15920 2022/06/02 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング