オープンソースのJavaScript/WebAssemblyエンジン「V8 release v8.0」が公開:ポインタ圧縮の効果が大きい
オープンソースのJavaScript/WebAssemblyエンジンの最新版「V8 release v8.0」が公開された。数週間後に正式リリース予定のWebブラウザ「Chrome 80」に搭載される。メモリ消費量が減ったために高速動作する他、プログラマーがバグを作り込みにくい仕組みを取り入れた。
オープンソースのJavaScript/WebAssemblyエンジン「V8」の開発チームは、2019年12月18日(米国時間)、最新版「V8 release v8.0」の公開を発表した。数週間後に正式リリース予定のWebブラウザ「Chrome 80」の安定版にも搭載される予定だ。
V8はC++で記述されており、ChromeやNode.jsなどに採用されている。ECMAScriptとWebAssembly規格に準拠しており、Windows 7以降、macOS 10.12以降、各種Linuxシステムで動作する。スタンドアロンでも、C++アプリケーションに組み込んで実行できる。
新版では、バグの修正はもちろん、パフォーマンスを大きく改善する改善を施した。
ポインタ圧縮の効果は大きい
開発チームはヒープメモリの削減を試みた。V8のヒープメモリにはさまざまなデータが登録されている。浮動小数点数の値やストリング文字、コンパイルされたコード、V8ヒープへのポインタ、小さな整数を表す「タグ付きの値(tagged values )」などだ。どのデータが多いのか、調査した結果、タグ付きの値がヒープメモリの大部分を占めていることが分かった。
タグ付きの値のサイズはシステムポインタと同じであり、アーキテクチャに依存する。例えば64bitアーキテクチャであれば64bit幅だ。
新版ではタグ付きの値(ポインタ)の圧縮により、ヒープメモリを平均40%節約できた。ポインタの圧縮は、下位ビットから上位ビットを合成できるので、下位ビットのみをヒープに保存すれば済むという発想で実現した。
メモリ使用量の改善は、パフォーマンスを犠牲にすることが多い。だが、今回の改善では実際のWebサイトにアクセスした際に必要な時間が改善した。3種類のWebサイト(Facebook、CNN、Google Maps)で検証したところ、ガベージコレクタ単体では20%、総合性能では8%の改善が見られた。
高次のビルトインの最適化が性能改善に役立つ
もう一つの改善点はTurboFanの最適化パイプライン内の制限を取り除いたことだ。この制限はこれまで、より高次のビルトインの積極的な最適化を妨げていたものだ。
これまでcharCodeAtの呼び出しは、V8のコンパイラ「TurboFan」からは不透明だった。このため、次のコードのようにユーザー定義関数の汎用(はんよう)呼び出しを生成していた。
const charCodeAt = Function.prototype.call.bind(String.prototype.charCodeAt); charCodeAt(string, 8);
だが、今回の改善により、V8はビルトインString.prototype.charCodeAt関数を呼び出すようになった。これによってTurboFanがビルトインの呼び出しを最適化によって改善でき、次のコードを記述した場合と同等のパフォーマンスを実現できるようになった。
string.charCodeAt(8);
この変更は、Function.prototype.applyやReflect.apply、さまざまな高次配列ビルトイン(例えばArray.prototype.mapなど)のような多くのビルトインに影響する。
オプショナルチェイニングによってプロパティアクセスのチェインを確実に動作するように改善
プロパティアクセスのチェインを作成する場合、コード上で中間値がNULL(nullish)かどうかをチェックする必要がある。nullかundefinedを判定する必要があるということだ。なぜならエラーチェックを作り込んでいないチェインはスローする可能性があるからだ。
かといって明示的にエラーチェックを行うチェインのコードは冗長になる。非NULL値だけでなく、次のコードのように全ての真の値もチェックしてしまうからだ。
// Error prone-version, could throw. const nameLength = db.user.name.length; // Less error-prone, but harder to read. let nameLength; if (db && db.user && db.user.name) nameLength = db.user.name.length;
この問題を解決するために、今回、オプショナルチェイニング(「?.」)を導入した。これを使うと、中間値がnullなのかundefinedなのかどうかを簡潔にチェックできる。オプショナルチェイニングは確実に機能するため、信頼性の高いプロパティアクセスチェインを作成できる。
今回の改良によって、中間値がnullまたはundefinedだった場合に、式全体がundefinedと評価できる。
// Still checks for errors and is much more readable. const nameLength = db?.user?.name?.length;
オプショナルチェイニングは、静的プロパティアクセスに加えて、動的プロパティアクセスと呼び出しもサポートしている。
nullish coalescingでデフォルト値処理が正確になる
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- ブラウザで実行可能な言語「WebAssembly」、Webの標準へ
W3Cは、プログラミング言語「WebAssembly」の標準化を完了し、そのコア仕様をW3C勧告として公開した。高パフォーマンスWebアプリケーションを実現する助けになる。 - Microsoft、プログラミング言語「TypeScript 3.7」を公開
Microsoftは、多数の新機能を提供するオープンソースプログラミング言語の最新版「TypeScript 3.7」を公開した。オプショナルチェイニングの実装やnullish coalescing演算子の導入といった改善を加えた。 - 最新版「Node.js 12」が公開、TLS 1.3に対応
Googleの「V8」JavaScriptエンジンで動作するサーバサイドJavaScript環境の最新版「Node.js 12」が公開された。TLS 1.3対応や診断レポート機能の実験的導入など多数の改良が施されている。