-
Notifications
You must be signed in to change notification settings - Fork 65
Open
Labels
Description
現在deployのGenerate new documentがボトルネックになっている。
例えば このビルド では全体で 3m7s のうち
実に 2m52s (約92%) がGenerate new document に費やされている。
Generate new document は make html を実行しており、
Lines 12 to 16 in 7ebdd16
html: | |
rm -rf target/html | |
mkdir -p target/html/doc | |
cp doc/*.jax vim_faq/*.jax target/html/doc | |
-cd target/html/doc ; vim -eu ../../../tools/buildhtml.vim -c "qall!" |
これは tools/buildhtml.vim で行われてる。
buildhtml.vim は MakeHtmlAll で全 *.jax を *.html に変換してから、各ファイルにJekyll用のYAMLヘッダーを付けている。
ファイルが多いのに加えてこの部分が順次直列に変化するために時間がかかっていると推測される。
よってこの部分をファイル単位で並列化できれば高速化が期待できる。
解決策案
MakeHmtlAllはファイルを列挙して MakeHtml を呼び出すようになっている。
なのでラッパースクリプトとして、
引数でファイルを1つ受け取ってMakeHtmlを実行しYAMLヘッダーを付与する
スクリプトを作れば、
makeファイルによる呼び出し側から並列度をコントロールできるようになると考えられる。
Vim内で並列化することはほぼ不可能(terminalとか駆使すればできるかもだけど)なので
やらないほうが得策。
残課題
- 一部ファイルのファイル名が異なる (mandatory)Makefileの依存関係見直し (mandatory)
2html.vimのボトルネックの把握 (optional)手を入れるほどではなかった実行時のプログレス表示、検討・改善 (optional)めんどいのでやらないTo pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
tsuyoshicho
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
koron commentedon Dec 19, 2021
いまちょっとやってます。成果でたらPRします。
koron commentedon Dec 19, 2021
#999 にて成果を公開。
けれども手元のWindowsではかなり遅くなってしまい
もともとの
make html
が 2m30s 程度だったのに対してmake html2
で 17mmake -j8 html2
で 3m14smake -j16 html2
で 2m54sぶっちゃけ地獄の遅さ。
ボトルネックはほぼほぼ tohtml#Convert2HTML なのは確認した。
推測では 2html.vim の読み込みパースが別プロセスになるので
もろもろキャッシュが効かなくなるんじゃないか、あたり。
koron commentedon Dec 19, 2021
FreeBSDでの計測結果
time gmake -j{n} html2
real 3m26.255s
real 1m43.496s
real 1m18.743s
real 1m6.536s
んーWindowsがとりわけ遅いってことかなぁ?
念のため同FreeBSDでの
time gmake html
の結果…おおよそ GitHub Actions の machine と同じ速度感。
なので make -j2 html2 で十分に速くはなりそう。
koron commentedon Dec 19, 2021
Windowsで遅い原因の1つには
taglist(".*")
で tags-ja を読むのが遅い(約4秒かかる)ことがわかった。パラレルでは140回やるので約9分余分にかかってる。
読み込んで整形したものを
js_encode()
&writefile()
で書き出し、それを
readfile()
&js_decode()
したら(≒JSONでのキャッシュにしたら)一瞬だった。これで置き換えることで8分、いや恐らく9分は縮められそう。
koron commentedon Dec 19, 2021
tags-jaにJSON形式のファイルキャッシュを噛ませたところ…
これが 3m になった。
Windows でさらに並列度をあげるとこんな感じ
-j16
- 47s-j8
- 53s566876b
koron commentedon Dec 20, 2021
残課題:
koron commentedon Dec 20, 2021
この誤解は観測データが偏っていたことによるもの。
ファイルによって tohtml#Convert2HTML が重いものと、そのあとの s:MakeLink が重いものがある。
結果的に前者が重いファイルだけを観測に用いてたことが誤解に繋がった。
詳細
s:MakeLink は s:GetTags で1回だけ taglist() を実行し、ほぼ定数時間がかかっていた。
このかかる時間は tags-ja ファイルのサイズで決まっており、
tags-jaはmake html実行時には固定となるので定数時間である。
ただしWindowsではこの定数時間が4秒とかなり長いため
全140ファイルをそれぞれ別プロセスで変換すると
各4秒のオーバーヘッドが積み上がり9分を超える膨大なロスに繋がっていた。
一方で tohtml#Convert2HTML は対象となる *.jax のファイルサイズに実行時間が依存する。
特に tags.jax や version8.txt などは大きいのでコチラの比重が重くなり、実行時間が長くなる。
パフォーマンスを計測するにあたり過去の経験から
「時間のかかるもので測った方がボトルネックが良く見える」
という前提でファイルサイズの大きい *.jax を計測対象としたため
「tohtml#Convert2HTMLがボトルネックである」という誤解が起こった。
実際はサイズが大きいファイルは多くない。
そのため全体としては tohtml#Convert2HTML の影響よりも
s:MakeLink (s:GetTags) の影響が強くなっていた。
koron commentedon Dec 27, 2021
GHA上にて 220秒くらいだったものが130秒くらいに高速化することを確認した。
#999 (comment)