Skip to content

英語候補の初回読み込みを高速化 / Speed up first English candidate lookup - #1269

Merged
KazumaProject merged 3 commits into
devfrom
codex/english-first-input
Nov 9, 2026
Merged

KazumaProject merged 3 commits into
devfrom
codex/english-first-input

Conversation

@KazumaProject

@KazumaProject KazumaProject commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

日本語

公開済みの Full 836 から生成した APK を Android API 37 エミュレーターに入れ、英語モードに切り替えた直後に最初の候補欄が空くことを再現しました。初回クエリは同梱の読み・単語・トークン辞書の準備を待ちます。旧実装は ZIP を展開して Java オブジェクトを復元しており、a では読み辞書の読み込みだけで中央値 224 ms かかりました。辞書を高速化した後も、候補欄は通常の候補の収集とマージが済むまで空いていました。

  • 同じ辞書データをビルド時にプリミティブ配列にし、APK からメモリマップしてまとめて読み込みます。
  • 英語モードで最初の英字を入力すると、候補欄が空の場合に大文字・小文字の候補を先に表示します。その後、通常の候補一覧に更新します。
  • 配布ビルドには新形式だけを同梱します。外部辞書は旧形式を読み込みます。

Android API 37 arm64 エミュレーターで各3回、アプリプロセスを停止してから計測した中央値です。画面計測は設定の検索欄で英語モードに切り替え、入力文字が見えたフレームから最初の候補が見えたフレームまでです。変更前の Lite デバッグビルドの英語辞書は Full 836 とハッシュが一致しています。

計測項目 変更前 変更後
最初の候補表示まで(Lite デバッグ、a) 677 ms 82 ms
変換セッションの初回クエリ(a) 418 ms 32 ms
変換セッションの初回クエリ(andr) 672 ms 119 ms

修正版 Lite AAB から生成・インストールした配布用 APK では、最初の候補表示は中央値 111 ms(107〜157 ms)でした。実機での計測は未実施です。

旧形式と新形式の辞書配列の全件比較、候補順、フレーズ変換、外部辞書切り替えを含む Android テスト8件が通過しました。Full・Lite・F-Droid の配布用アセットを検査し、Lite AAB の bundletool validate と端末用 APK の生成を確認しました。英語辞書3ファイルの合計は、Full 836 の同梱データとの比較で AAB 内が 408,044 バイト、インストールされるベース APK 内が 17,173,689 バイト増えます。

追加の高速化

最初の英字候補を入力処理中に反映し、空の候補欄への初回挿入は差分処理を待たずに行います。英語モードのタブ非表示時は、既存の並行検索を使ってエンジンとユーザー辞書・テンプレートを取得します。通常の候補クエリには従来と同じモードを渡します。

追加修正の前後で Lite 配布用 APK を入れ替え、設定の検索欄で各3回測りました。入力文字が見えてから最初の候補までは中央値 155 → 100 ms、辞書候補の A1 までは 300 → 288 ms でした。修正後の最初の候補表示は 86〜390 ms で、390 ms の回はキーボード自体の再描画も同時に遅れました。実機での表示時間は未確認です。

候補欄・リクエストの単体テスト16件と英語辞書の Android テスト8件が通過しました。Lite AAB をビルドし、bundletool validate を実行しました。

English

I reproduced the empty suggestion strip after switching to English using APKs generated from the published Full 836 bundle on an Android API 37 emulator. The first conversion query waits for the bundled reading, word, and token tables. The old loader inflated ZIP streams and deserialized Java objects. For a, loading the reading table alone took a median of 224 ms. After speeding up the dictionary, the strip still waited for the full candidate query and merge.

  • Generate primitive arrays from the same dictionary at build time. Memory-map the assets from the APK and bulk-read the arrays.
  • Show case variants when the user enters the first ASCII letter in English mode and the strip is empty. Replace them with the regular candidate list when it is ready.
  • Ship the new bundled format in distribution builds. Imported dictionaries still use the existing reader.

These are medians of three trials per condition after stopping the app process, on an Android API 37 arm64 emulator. The display measurement runs from the frame showing the typed letter to the first frame showing a suggestion, in Settings search. The baseline Lite debug build's English assets matched the Full 836 assets by hash.

Measurement Before After
First visible suggestion (Lite debug, a) 677 ms 82 ms
First conversion-session query (a) 418 ms 32 ms
First conversion-session query (andr) 672 ms 119 ms

The installable APKs generated from the updated Lite AAB showed a median of 111 ms to the first visible suggestion, with a range of 107–157 ms. Physical-device timing remains unverified.

All eight selected Android tests passed, including full dictionary array comparison, candidate ordering, phrase conversion, and switching to a legacy external dictionary. I checked the Full, Lite, and F-Droid distribution assets, validated the Lite AAB with bundletool, and generated device APKs. Compared with the bundled Full 836 English tables, the three replacement files add 408,044 bytes to the AAB and 17,173,689 bytes to the installed base APK.

Follow-up latency changes

Publish the first English case candidates during composing input and insert them directly into an empty strip. For English input with the candidate tabs hidden, reuse the existing parallel lookups for the engine, user dictionary, and templates. The regular query still uses its original mode.

I alternated Lite distribution APKs on the same emulator and recorded three runs per build in Settings search. From the first frame with the typed letter, the median was 155 → 100 ms for the first visible candidate and 300 → 288 ms for the dictionary candidate A1. The updated build ranged from 86–390 ms for the first candidate. In the 390 ms run, the keyboard repaint was also delayed. Physical-device display latency remains unverified.

All 16 candidate UI and request unit tests and all 8 English dictionary Android tests passed. I built the Lite AAB and ran bundletool validate.

@KazumaProject
KazumaProject merged commit debc07d into dev Nov 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant