- 入力が止まってから配置し直されます
- 計算済みの数式は記憶されます
- カーソルが別の場所にある間は再計算されません
第 2 章
なぜ Akileas はこれほど速いのか
多くのエディターは、文書が長くなると「表示する前に考える」ようになり、入力中のもたつきが 体感できるようになります。Akileas は、それが決して起きないように設計されています。 キーを押した瞬間には、画面はすでに更新されています。残りの細かな組版は 裏側で静かに埋められ、あなたと書いている文字の間に割り込むことはありません。
2.1 キー入力は、その場で表示される
エディターの内部では、「キーが押された」という出来事は 2 つに分けて扱われます。 すぐに表示する部分と、あとから精密に整える部分です。 前者は必要最小限のことだけを行うので、同じフレームの中で必ず画面が更新されます。 後者はやることは多いものの、時間をかけてよく、新しい入力が来ればいつでも中断できます。
すぐに起きること
同じフレームの中で終わらせる必要があります。そうでなければ、遅れとして見えてしまいます。
- カーソル位置に 1 文字を入力します
- その 1 行だけが描き直されます
- 文字とカーソルが正しい位置に置かれた状態で、画面が更新されます
あとから起きること
裏側で実行され、入力の邪魔をすることはありません。
- エディターが、文書のどこが変わったかの解析を始めます
- 影響を受けた部分だけが再計算されます
- シンタックスハイライトと細かな組版が滑らかに反映されます
- その間も入力し続けていれば、古くなった結果は自動的に破棄されます
そのため、10 万行の文書に入力するときも、白紙のページに入力するときとほとんど同じ感覚で 済みます。実測では、キーを押してから画面が更新されるまでの時間はわずか 37 マイクロ秒で、1 フレーム分の予算(8.33 ms)の 100 分の 1 にも満たない ほどです。
2.2 変更した行だけが再計算される
ふつうの文書は、長くなるほど動作が重くなります。1 文字入力するたびに全文を最初から 読み直しているからです。Akileas はそうしません。
Akileas は文書を 2 つの階層で読み取ります。一方はどこが段落で、見出しで、 コードブロックで、リストなのかを記録し、もう一方はあるブロックの中にある 太字やリンク、数式を記録します。本文中の数語を書き換えても外側の構造はまったく 変わらないため、編集中のその 1 行だけを読み直せばよく、残りの 99,999 行は そのまま再利用されます。
NOTE
ふつうの文章を入力しているときにまったく遅れを感じないのも、そして # の
ように見出しの構造を変え、ブロック全体を巻き込む入力だけが裏側に少し余分な時間を
かけるのも、同じ理由です。それでも画面の更新は 85 マイクロ秒以内に終わっているので、
裏側が働いていることに気づくことはありません。
2.3 互いに足を引っ張らない数式・図・表
数式、Mermaid の図、表は、文書の中でもっとも「高コスト」な 3 種類の内容です。これらが 1 つの更新経路を共有していると、1 文字入力するたびに図の再計算が走り、入力が途切れ 途切れになってしまいます。
Akileas はこれらを独立させています。実際に変わった種類だけが再計算されます。 本文に入力しても、すぐ隣に描かれている構成図が乱れることはありません。
- 表示領域に見えている図だけが変換されます
- 拡大や移動をしても図が描き直されることはありません
- 図の形状はキャッシュされて再利用されます
- 列幅は実際の表示幅に合わせて調整されます
- 中国語と英語が混在した文章でも桁がそろいます
- セルを編集しても、影響はその表だけにとどまります
2.4 10 万行のどこへでも瞬時に移動できる
非常に長い文書でスクロールバーをドラッグすると、多くのエディターはまず固まり、そのあとで 飛ぶように移動します。原因は、ドラッグした位置が何行目にあたるのかを知るために、 先頭からすべての行の高さを足し合わせているからです。
Akileas は、文書全体の高さを、すばやく検索できる索引としてまとめています。文書が どれだけ長くても、位置を特定するための計算量は長さの対数に比例するだけです。 スクロールバーを 85% までドラッグすれば、それが何行目の何文字目なのかを 数マイクロ秒で答えることができます。まだ計測していない行は、スクロール中は 平均的な高さで見積もられ、ドラッグを続けるにつれて精度が上がっていくため、飛びや ちらつきは起きません。
2.5 クラッシュや電源断で作業を失うことはない
保存は 1 つの操作に見えますが、書き込みの途中で電源が落ちると、書きかけのファイルが、 せっかくの完璧な下書きを台無しにしてしまうことがあります。Akileas はこれを避けるために、 まずコピーを書き、それを検証してから、はじめて元のファイルを一気に置き換えます。
- 1 新しい内容を組み立てる 現在の内容を 1 つの完全なファイルにまとめます
- 2 一時コピーを書き出す まず一時ファイルに書き出します。この時点では元のファイルは手つかずです
- 3 内容を検証する 書き出したデータが完全で正しいことを確認し、ディスクに確実に書き込みます
- 4 一気に置き換える コピーを元のファイルとアトミックに入れ替え、書きかけの状態を残しません
- 5 タイムマシンに記録する いつでも比較したり巻き戻したりできる履歴を残します
さらにエディターは、軽量で検証済みの編集記録を追記し続けています。電源が落ちたあとでも、 次にその文書を開いたときにこの記録を自動的に確認して再現し、保存していなかった内容を 返してくれます。
2.6 土台にあるもの
これらの性能は、いくつかの根本的な設計判断から生まれています。ブラウザーエンジンの上に 作られたエディターとは、出発点からまったく違う道を進むという選択です。
ネイティブにコンパイルされ、中にブラウザーエンジンを持たない
アプリケーション全体がネイティブコードにコンパイルされ、システムの描画 インターフェースを直接呼び出します。ブラウザーエンジンを内蔵していないため、起動に 数秒待たされることも、数百 MB のメモリを消費することもありません。
ガベージコレクションによる停止がない
メモリをいつ解放するかをコンパイラーがコンパイル時に決めるため、アプリケーションの 実行中にガベージコレクションは行われません。数秒ごとに動作が引っかかる原因となる フレーム落ちは、ここでは起こりません。
GPU が直接描画する
文字、ベクターグラフィックス、インターフェースの要素はすべて GPU が描画し、 120 FPS の高リフレッシュレートディスプレイと、くっきりとしたサブピクセル描画に 対応します。文書がどれだけ長くても、スクロールとズームは滑らかなままです。
メモリとキャッシュの上限が決まっている
画像、数式、図にはそれぞれ明確なキャッシュの上限があり、それを超えると、最後に 使われた時刻が最も古いものから自動的に破棄されます。そのため、非常に大きな文書を 長い時間編集し続けても遅くなることはありません。
こうした設計の直接の結果です。軽い文書ではメモリ使用量はおよそ 25 MB から 45 MB、 10 万行の文書でも 60 MB から 110 MB の間で安定し、編集を続けてもどちらも増えて いきません。