k1LoW/deckを急激に(100倍以上)高速化する方法

3K Views

November 14, 25

スライド概要

profile-image

Fellow at Henry, Inc. Tech SaaSのPdM、スタートアップ取締役CTOや外資スタートアップのIC等を経て現任。好きな言語はGoとPerlと中国語で雑なOSSを200以上量産している。3 times ISUCON winner. 著書「みんなのGo言語」共著他。Podcast: https://oss4.fun/

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

k1LoW/deckを急激に (100倍以上)高速化する方法 Masayuki Matsuki a.k.a Songmu @ YAPC::Fukuoka 2025

2.

Profile ● ● ● id: Songmu (ソンムー) Masayuki Matsuki / 松木雅幸 Blog: おそらくはそれさえも平凡な日々 ○ ● ● ● http://www.songmu.jp/riji/ 好きな言語は、PerlとGoと中国語 3 Times ISUCON Winner OSS作家 ○ ○ ○ 200+ OSS Developer 入門監視 付録C 執筆・「みんなのGo言語」共著者 Podcast ■ 趣味でOSSをやっている者だ #oss4fun

3.

OSS作家として 色々なOSSを作ったり、継続メンテナンスしています。 ● x-motemen/ghq (3325 stars) ○ ● k1LoW/deck (938 stars) ○ ○ ● ソースコードリポジトリ管理ツール MarkdownからGoogle Slideを生成するツール このスライドはdeckで作成されています tagpr (257 stars) ○ GitHub上でのリリースエンジニアリング民主化のためのカスタムGitHub Action

4.

最近の新作OSS AIにより捗っている。 ● chape ○ ○ ● laminate ○ ○ ● 文字列の画像化管理ツール deck でコード文字列の変換の際に便利 action-push-to-another-repository ○ ● MP3のチャプターやメタデータ編集ツール Podcastの編集などで便利 (使って欲しい!) あるリポジトリの内容を別リポジトリにpushするGitHub Action action-create-branch ○ ブランチを作成するGitHub Action

5.

k1LoWさんの先週のスライド ● 合わせて読みたい ○ https://speakerdeck.com/k1low/phpconfuk-2025

6.

Agenda ● ● ● ● ● k1LoW/deck について コントリビュートをどのように始めたか 大きなデザイン変更をどのように進めたか deckを100倍速にしたパフォーマンスチューニング パフォーマンスチューニングの一般的な心得 OSS貢献やパフォーマンスチューニングについて実例を踏まえてお話します。

7.

k1LoW/deck MarkdownからGoogle Slideを生成するツール

9.

コントリビューション ● ● 7月8月に集中的にコントリビュート 7月は1月で1万行近くのコントリビュート ○ Claude Code Maxがなかったら無理だった

10.

pull request爆撃 ● ● 2ヶ月で実に100件以上のpull request 今年は k1LoW/deck 開発に熱狂した年だった

11.

1000 stars 目前…! ● ● 7月~9月でめっちゃ伸びた starお願いします!

12.

主立った貢献 ● ● ● ● ● Frontmatterサポート スライドタイトルとヘッディング要素の対応の仕様変更 インテグレーションテストの改善 Markdown仕様準拠 パフォーマンス改善

13.

100倍以上のスライド生成時間短縮 (場合によっては) ● 15分 -> 10秒以下 ○ 150枚程度で画像が少ないのスライドの場合 今日はその辺りの貢献やパフォーマンスチューニングについてお話します

14.

使いはじめたきっかけ

15.

業務でのプレゼンテーション機会の増加 ● ● 技術顧問やアドバイザリ業務など 自作のHTMLプレゼンツールからの乗り換え ○ ○ ちゃんと体裁を整えたかった Markdownをスライドに変換するフローは維持したかった

16.

k1LoW/deck https://github.com/k1LoW/deck ● 名称は deck (デック) ○ ● ● ● 検索性のために "k1LoW/deck" を表記されることも多い k1LoWさんの今年の新作OSSということで気になっていた tadsanやlacolacoさんなどがすでに利用しているのを把握していた 試しに使ってみることに

17.

Repro社でいきなり実践投入 ● Goの「野暮ったさ」とどう付き合うか ○ コード例も多いスライドだったので大変助かった

18.

思っていた以上に体験が良かった ● Googleスライドをプレゼンテーションツールとして使えることの利点 ○ ○ ● 既存のテンプレート資産の活用 スピーカーノートなどスピーカーパネルの活用 ■ スピーカーノートは英語プレゼンでマジで有用だった Googleスライド側での調整は極力維持される

19.

課題に感じたこと ● Frontmatter未対応 ○ ● スライドタイトルとヘッディング要素の対応 ○ ● H1要素以外もスライドタイトルにしたい Markdown対応の不十分さ ○ ● 私の既存のプレゼンツールはFrontmatterを使っていた Markdown仕様不準拠が故に、直感的に動かないところ パフォーマンス問題 ○ 130枚のスライド生成に15分かかった

20.

面倒くさいMarkdownオタク ● 既に良い物なので「自分の道具」としても完成度を高めたかった ○ ○ あくまで 私のユースケース には不十分だった k1LoWさん的にはかなり十分だったし、利用者も存在した

21.

どういう順序で貢献を積み上げたか ● ● ● ● ● 取り急ぎ欲しい機能提案と実装 小さな貢献・観察と整理整頓 信頼の獲得 大きめの変更の相談と実装 全体のデザインに関する議論や意思決定 この辺りについて話していきます。

22.

コントリビュート開始 小さな貢献・観察と整理整頓

23.

Frontmatterサポートの追加 最初のpull request

24.

FrontmatterへのpresentationID設定 一応別pull requestに分割

25.

Frontmatterサポート ● Markdown先頭にメタデータを埋め込む拡張記法 ○ ○ ● YAML形式が多い (TOMLやJSON形式がサポートされていることも) deckはYAML形式のみ対応 JekyllやHuboなどで広く使われている ○ ○ 個人的には馴染みが深く、対応して欲しかった ■ 初手のp/rとして結構激し目の提案だったかもしれない ■ 個人的にかなり欲しかった k1LoWさん的には盲点だったようだ

26.

バグ修正 ● いくつかのちょっとしたバグ修正

27.

OSSには結構バグがある

28.

Songmuもやらかしている ● ● --from オプションを --base オプションにリネームしたときのバグ OSSにはこういうしょーもないバグがある ○ yukukotani++

29.

URLリンク記法サポート ● 出典明記のためにもURLリンク記法はサポートしたかった ○ ○ 逆に <> で囲われていない場合のオートリンクは非サポート オリジナルMarkdown, CommonMark, GFM準拠

30.

watchプロセスの改善 ● ● 保存しまくると実行キューが詰まって重くなる問題の改善 1秒程度のデバウンス間隔も設けた ○ → かなり快適に!

31.

lintやreviewdogの修正 ● ● ● reviewdog (GitHub Actions上でのlint実行) が動かなくなっていた 直すとともにlint警告も修正 一人開発だとありがち ○ ○ この辺ちゃんと民主化するの大事 貢献を受け付けやすくなる

32.

信頼貯金の積み上げ ● ● ● ● ちょっとしたバグ修正や機能追加 小さな改善 k1LoWさんとはお互い知った仲ではあった この辺で、ある程度コードの全貌も把握できた

33.

Coding Agent (AI) 活用 ● 私がコントリビュートする前に既に使われている形跡があった ○ ● 逆にリファクタリングもかなりすることになった ○ ○ ● ● なので私も遠慮なく使った 粗い部分も多かったので書き直しも多々 AIによる負債の積み上げとその返却を早々に体験できた 整理整頓できる部分が多かったので全貌の把握には役立ったとも言える 細かいチューニングではCoding Agentを使う局面は減っていった ○ 後述

34.

最初の大きな変更提案 スライドのタイトルの見出しレベルの仕様追加

35.

スライドのタイトルの見出しレベルの仕様追加 ● ● ● 元々はH1がスライド要素で固定だった スライド内で一番レベルが高い見出しがスライドタイトルになるように変更 これは個人的にかなり欲しい機能だった ○ これはそれなりにすんなり入れてもらえた

36.

見出しレベルに応じたレイアウト自動適用設定 ● これはかなり議論が紛糾することになる

37.

渾身のexample

38.

最終的にはCEL記法のDSLをFrontmatterに記述する方向で万事解決 詳しくは先述のk1LoWさんのスライド及び、48: 特別編: 突発deck開発者会議 @ 2025-07-11 (k1LoW) をご覧下さい。

39.

インテグレーションテストの改善 より貢献しやすく

40.

この時点の気付き pull requestが送りやすい! ● ● テストの充実 goldenテストの存在 ○ ● Markdownがどういう中間表現に変換されてリクエストになるかが明確 pull requestにテストケースを追加しやすい ○ ○ テストケースをAIに作らせやすい テストが通れば安心してレビューに出せる ■ → …?

41.

気付いていなかったこと ● デフォルトでスキップされているインテグレーションテストの存在 ○ ● 実際にGoogleプレゼンテーションを作成して表示を確認するテストケース Googleスライドから中間表現への逆変換のケア ○ ローカルのMarkdownとGoogle Slideの無いよう比較の為に必要だった ■ 実は今ではパフォーマンスが向上した結果そこまで拘る必要がなくなった ■ 更新対象の抽出を厳密にやらずとも一括更新で困らなくなったため

42.

インテグレーションテストの属人性 ● ● セットアップが大変だった 時間もかかっていた ○ ● ● 25分程度 flakyでもあった これをk1LoWさんが手元で動かしてからリリースしていた ○ ○ 属人性が高い! 気付いたときに申し訳ない気持ちになった

43.

インテグレーションテストの改善 ● ● k1LoWさんによる改善 chromedpでスライドのスクリーンショットを撮るgoldenテスト ○ ● 差分の確認も簡単に セットアップも比較的簡単に

44.

インテグレーションテスト高速化 ● 事前にプレゼンテーションプールを作って使い回すように ○ ● 同時に並列実行するように (3並列・今は2並列) ○ ● ● 以前はテストケースごとにプレゼンテーションを新規作成していた APIリミットがあるので、並列度を増やしても頭打ちになる この辺りの改善で一時、余計flakyにしてしまったが今は落ち着いた 後述のパフォーマンス改善も含めて今では7分程度で完了するように ○ もっと劇的改善アイデアはあるがやっていない

45.

インテグレーションテスト整備の効用 時間は多少かかるモノの、自信をもってリリースできるようになった。

46.

インテグレーションテストのさらなる民主化 ● ● 手元じゃなくても動かせるように 外部からのpull requestに対しても動かせる ○ ○ ● "integration-test" ラベルをprに付与することでトリガー (pull_request_target を使っているので若干危険 / 改善余地あり) コントリビューターがインテグレーションテスト失敗を認識しやすく ○ ○ メンテナ・コントリビューター双方の負担軽減のために重要 どこがどのように落ちているかはちょっと分かりづらいので改善余地あり

47.

動かす仕組み ● Google CloudのWorkload Identity Federation + サービスアカウント ○ ○ ○ ● GitHub Actions上でインテグレーションテストを実行可能に テンポラリの認証情報がGitHub Actions上に渡される ■ リポジトリにシークレットを設定する必要もない 図は Workload Identity Federationを図で理解する より Google Driveを使うのでサービスアカウントが必要 ○ ○ ○ ○ サービスアカウントはGoogle Drive容量を持てない制約がある 有料のGoogle Workspaceの共有ドライブを利用 Songmuの個人事業のGWS及びGoogle Cloudプロジェクトを利用 ほんのちょっとお金かかってるのでスポンサー歓迎

48.

表現力の改善 Markdownサポートの強化

49.

当初の最低限なMarkdown対応 ● リスト及び一部のインライン記法のサポートに留まっていた ○ ● パラグラフの扱いの不備 ○ ● アドホックな実装 実はここの難易度が高かった k1LoWさんのユースケースは満たしていた ○ 私としては最低限のMarkdownは一通り表示されて欲しかった 利用者がMarkdownだと認識して記述した結果、思った通りに表示されないの は(特にMarkdownオタクにとっては)ストレス

50.

慎重に議論をしながら進めた ● ● issue上での議論と認識合わせ 私もpull requestばかり送っているわけじゃない

51.

インピーダンスミスマッチの解消 以下の3つをどのように対応させるか議論を尽くした。 ● ● ● Markdown HTML Google Slide

52.

仕様をベースに議論する ● HTMLの仕様 ○ ● ある要素がブラウザのデフォルトCSSではどのようにレンダリングされるべきか Markdownの仕様 ○ ○ ○ CommonMark GitHub Flavored Markdown (GFM) (オリジナルMarkdown)

53.

Markdownの簡単な歴史 ● ● ● オリジナルMarkdown (2004年) CommonMark (2014年~) GitHub Flavored Markdown (GFM) (2012年~, 2017年~)

54.

オリジナルMarkdown (2004年) ● John Gruber氏によるMarkdownの最初の提案 ○ ○ ● https://daringfireball.net/projects/markdown/syntax Markdown.pl スクリプトが実装であり仕様 ミニマムで曖昧な仕様だったため、各言語・プラットフォームに移植・拡張さ れ、方言が乱立 ○ GitHub Flavored Markdownもその1つ

55.

CommonMark (2014年~) ● Markdown仕様標準化プロジェクト ○ ● オリジナルMarkdowの記法の曖昧な部分を明確化し、仕様として定義 ○ ● ● ● https://commonmark.org/ 拡張記法は殆どない 最新specは0.31.2 (2024年4月) 色々あったが世に広く受け入れられた感がある 元々Standard Flavored Markdownというプロジェクト名で進められていた (2012~) ○ ○ John Gruber氏の物言いが付いて名称変更 Standard Markdown is now Common Markdown

56.

GitHub Flavored Markdown (GFM) (2012年~, 2017年~) ● GitHubが独自拡張したMarkdown仕様 ○ ○ ● ● 当初はsundownをベースとした実装 2017年にCommonMarkベースへの移行宣言とともに仕様が公開 ○ ● テーブル記法など https://github.github.com/gfm/ A formal spec for GitHub Flavored Markdown みんな大好きなGitHubのMarkdownと思うかも知れないが ○ ○ 実はGFMはgithub.comサイト上の挙動とは異なる 仕様内に矛盾があることも指摘されている

57.

goldmarkが凄過ぎる https://github.com/yuin/goldmark ● ● Go製のMarkdownパーサー CommonMark準拠 ○ ● それに加えてGFM等の記法も拡張として追加できる deckはMarkdown周りはgoldmarkにお任せしている

58.

Markdownの扱いの適正化方針 ● まずはCommonMarkの記法を網羅する ○ ● その上でGFMの記法で欲しいものがあれば追加 パラグラフ及び改行の扱いの適正化 ○ ○ この辺りはGoogle Slides APIのドキュメントが不十分で調査が必要だった 改行って3種類あんねん

59.

改行って3種類あんねん ちゃんと意識している人も少ないのでk1LoWさんとも丁寧に認識を合わせた ● ● ● Soft line break: テキストの折返し (≠改行) Hard line break: 明示的なブロック内のインライン改行 段落・ブロック区切り

60.

Soft line break: テキストの折返し(≠改行) 文中の折り返し。 ● Markdown ○ ○ ● 文書中の単なる改行文字 例えば80文字幅での改行など HTML ○ 文書中の単なる改行文字 レンダリング時には改行として扱われず、後続にテキストが続く場合には半角スペー スとして表示される。 (この挙動は空白で分かち書きされない言語では好ましくない為、CSS3のSegment Break Transformation Rulesで調整可能。約物関連はまだ議論中)

61.

Hard line break: 明示的なブロック内のインライン改行 パラグラフ内の改行。 ● Markdown ○ ● HTML ○ ● <br>要素 Google Slide内での操作 ○ ● 行末の2個のスペース、もしくは生の<br>要素 Shift + Enterで挿入 Slide API (undocumented) ○ ○ スライド内のインライン改行は垂直タブ (\v)に変換されてレスポンスに含まれる 垂直タブをテキスト内に含めてAPI送信するとインライン改行が挿入される マージンが狭い改行としてレンダリングされる。

62.

段落・ブロック区切り ● Markdown ○ ○ ● HTML ○ ○ ● 新たなブロック要素の開始時 <p>, <li> 要素など Google Slide内での操作 ○ ● 2連続の改行 新たなブロック要素の開始時 Enterキー Slide API ○ ○ 改ブロックはレスポンスでは \n とelement.paragraphMarker で表現される APIに改行文字 (\n)を送信すると改ブロックになる 次の段落や、次のリスト項目などとしてレンダリングされる。

63.

💡 Google Slides APIのインライン改行の扱いの発見 ● パラグラフ内のインライン改行は垂直タブ \u000b, \v に対応している ○ ○ ● この仕様はドキュメントされていないがstackoverflowなど何ヶ所かで報告されている google-apps-script-replacetext-vertical-tab ■ App Scriptなどの他のAPIもそうなっている物も多いようなのでおそらくこの振る舞いは変 わらないと期待している この辺りは実際にAPIの挙動を観察して把握した ○ 観察用のツールはAIに作ってもらった つまり、<br>や、Hard line break相当の改行は、 "\n" ではなく "\v" (垂直タブ) に 変換してAPIリクエストを送る必要がある。この発見がブレークスルーだった。

64.

改行やパラグラフ周りの整理 ブロックや改行の扱いの適正化 ● 元々Hard line breakに対応していなかった ○ ● Soft line breakと混同していた ブロック区切りの扱いも整理した ○ 元々結果整合的に何とかしていたのを綺麗にした

65.

その後の表現力改善 ● CommonMarkの記法一通りに加え、GFMのテーブル記法等をサポート ○ ○ 土台を整えれば後は結構簡単だった ■ goldmarkが素晴らしかった 詳しくはhttps://github.com/k1LoW/deck/blob/main/docs/markdown.md を参考のこと

66.

(補足) 改行の振る舞いの変更 ● 行末に2つのスペースを入れた時のみHard line break (明示的な改行) になる Markdownの記法は余り好まれていない (私は好き) ○ ● CommonMarkやGFM仕様でもそうなっている GitHubのサイト上では入力した改行文字はそのまま改行として表示される ○ ○ この挙動に準拠する為に breaks: true というオプションを設定できるようにした 他のツールやライブラリも同様のオプションを提供している

68.

(余談) CommonMarkの仕様提案 ● void elementの扱いについて仕様提案のpull requestを送っている ○ issue上では比較的前向きな返答をもらったが進んでいない

69.

パフォーマンス改善 結果的に爆速に

70.

発端 ● スライド内のプレースホルダーをクリアする処理が無駄に感じたのでまとめた ○ ● ● APIエラーを握りつぶしている部分もあった スライド毎に毎回プレースホルダーの数だけAPIを叩いていたのが1リクエスト にまとまった → これがかなり効いた ○ ○ インテグレーションテストの時間が倍以上に早くなった 20分程度 -> 10分弱

71.

APIリクエストをまとめるとパフォーマンス改善できることに気付く

72.

Google Slides APIのリクエスト制限 1秒に1回書き込みリクエストが送信できると考えると分かりやすい ● ● ● deck はその仕組み上、結構APIを叩く作りになっている 叩き過ぎるとレートリミットがかかる 参照: 使用制限 | Google Slides ○ プロジェクトを共有する場合、人数が多くなる場合はプロジェクトを分けた方が良いかも ■ 会社などで利用する場合 reqs / min 読み取り 書き込み プロジェクト全体 3000 600 ユーザー辺り 600 60

73.

とにかくバッチリクエストだ! ● ● 複数の操作をバッチリクエストにまとめられる 1バッチリクエストも1書き込みリクエストとしてカウントされる(!) ○ ● 1バッチ内に含められるリクエスト数上限も記述されていない(!) → 要はとにかくバッチリクエストにすれば良い

74.

deckがスライドを操作する順番 ● 新規スライドの追加 ○ ● ● ● 中間の追加も一旦末尾に全部追加する 既存スライドの更新 不要スライドの削除 スライドの入れ替え ここの処理がハンガリアンアルゴリズムできれいに並んでいたのが良かった。 参考: deckのスライド更新処理を改善した - Copy/Cut/Paste/Hatena

75.

当初の処理の流れ ● スライド毎に一枚一枚処理する流れになっていた ○ ● 1スライドに対して複数のAPIリクエスト スライド内の画像も順次貼り付けられていた

76.

画像の取扱 その他のAPIリクエスト ● ● ● deckはGoogle Slide APIの他にGoogle Drive APIも利用している 画像を取得後一旦Google Driveに一次画像をアップロード そこから公開URLを取得しGoogle Slideに貼り付ける ○ ● ファイルの公開化権限が必要なのはその為 ■ (現在は公開URLであればDrive経由しない形に変更した) スライドを順次処理していく中で画像を逐次アップロードしていた ○ 非効率

77.

画像の事前アップロード

78.

画像アップロード効率化 ● 各スライドの処理に移る前に全てのスライド内の画像を収集し画像アップロード ○ ○ アップロードが開始されたら終了を待たずにスライド処理に移行 ■ goroutineによる非同期処理かつ並列アップロード スライド処理時に必要な画像をすぐに利用できるように ■ 必要な画像がアップロードされていない場合は待機する

79.

(余談)コードブロックの画像変換機能 ● ● ● 素晴らしい機能 このスライドのMermaidの図もそれを利用しています 一度キャッシュ化のpull requestを送ったが、キャッシュは意図しない挙 動を引き起こす可能性があるので見送られた

80.

Songmu/laminate 爆誕 https://github.com/Songmu/laminate ● ● ● 言語ごとの画像変換コマンドの使い分け設定 キャッシュ機構も備える deckと併せてご利用下さい

81.

スライド削除処理のバッチ化

82.

削除処理のバッチ化 ● ● 不要なスライドの削除処理を1枚毎にやっていたのを1リクエストにバッチ化 例えば10枚削除する場合、10リクエスト -> 1リクエストに ○ ○ とは言え削除の発生は少ないの劇的なパフォーマンス向上にはならなかった その後の改善のヒントになった

83.

スライド追加処理のバッチ化 (天啓1) ● 5分くらいのスライド生成が2分40秒くらいになったとコメントされてい る ○ 当時は到達点かと思っていた

84.

スライド追加処理のバッチ化 ● 新規スライドの枚数分、空白のプレゼンテーション末尾にまとめて追加 ○ ● それまではスライド追加毎にスライド作成APIを叩いていた ○ ● 元々新規スライドはプレゼンテーション末尾に追加する挙動だった ■ 中間のスライドであってもまずは末尾に追加されてから後続で入れ替え処理 ■ この挙動はかなり助かった スライドを追加して、そのスライドにコンテンツを入れ込んでいた 100枚新規スライドを追加する場合、100リクエスト -> 1リクエストに

85.

天啓の瞬間

86.

1スライド1APIリクエストの壁 ● ● この辺りがチューニングの到達点だと思っていた スライド1ページ毎に1 APIリクエストは最低限必要だと思っていた

87.

スライド更新のバッチ化 (天啓2)

88.

スライド一括追加処理後のフローチャート 新規スライドの更新と既存スライドの更新はほぼ同じ処理だと見なせる

89.

スライド更新処理まで1リクエストにバッチ化 (最終形) ● ● 全てのスライド更新処理を1本化 工夫すれば複数スライドの更新を1リクエストにバッチ化できることに気付いた ○ これで新規プレゼンテーション作成は理論上2リクエストで完了する ■ 新規スライド一括追加 ■ スライド一括更新

90.

実現の瞬間 ● バッチリクエスト内に入れ込めるリクエスト数上限はドキュメントされていない ○ ○ ● が、かなり大量に入れ込めることが分かった 一応1000件 (10MB程度) 毎に分割するようにしている 元々スライド枚数 x 7, 8 API requests ○ 全部で数requestsにまで削減

91.

感謝の声

92.

喜びの声

93.

更なるチューニング余地 既に十分に速いのでそれほどモチベーションは高くない (patches welcome!) ● スライドの処理が並べ替えまだバッチ化されていない ○ ● Markdown内の画像取得 ○ ● プレゼンテーションの新規作成より更新の方が遅いという奇妙な状況が発生している Markdownパース時に順次取得しているので非同期で並列取得すれば少し速くなりそう スライドfreeze機能の悩ましさ ○ ○ ○ 元々は完成したスライドの意図せぬ上書きを防ぎつつ、余計なリクエストを減らす機能だった チューニングされた結果、旨味が減っている 逆に状態管理上悩ましくなってしまった ■ スライド側はfreeze情報を保持できていない ■ 特に中間に新規スライドが挿入されてページがずれたときに状態を同期するのが難しい

94.

コラボレーターに加えてもらう 共同メンテナンス体制に

95.

メンテナンス方針 ● お互い好きなときにリリースして良い ○ ● ● 大きな変更など不安な場合は適宜相談 基本的にはオリジナル作者のk1LoWさんの意向は尊重したい 要望や質問大歓迎です ○ YAPC会期中に是非話しかけてください

96.

AIの使い方の変化 ● ● コードの年齢や修正個所に応じて適切なツールは変化することを実感 繊細なチューニングや大幅なデザイン変更等はまだ人手が必要

97.

パフォーマンスチューニング心得 我々凡人の現実的な考え方

98.

Songmuが考えていること ● ● ● ● ● ● ● 速くするのではなく「遅くしない」 観察することと整理整頓 データ構造と計算量の重要性 自然な書き方を優先する 速いライブラリ・速いコードを書ける人に頼る 並列処理は計算を速くしない 資源のフェアユース

99.

速くするのではなく「遅くしない」 これがとにかく大事 2014年にGo作者のRob Pike氏が日本に来たときにこんなことをおっしゃって いて感銘を受けた 「Goは遅くない言語である」という言い回しは個人的に気に入っている。 Go(のコンパイル)は速いわけではない、遅くないだけだ

100.

Rob Pikeのプログラミング5箇条 Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is. Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest. Rule 3. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.) Rule 4. Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures. Rule 5. Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming. -- Rob Pike's 5 Rules of Programming

101.

Rule 1., Rule 2「推測するな計測せよ」 ● ● 皆様ご存知のやつ Rule 1.「当て推量するな」、Rule 2.「計測せよ」 ○ ● Rule 2. は「速度計測する前にチューニングするな」と訳せる 速度計測する前に、あてずっぽうでチューニングを始めるなと言う話 Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is. Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.

102.

「計測する前に観察せよ」 ● ● 最近考えていること どこを計測するかは観察(observe)してからではないと分からない ○ ○ ● 特に複雑なシステムだと だからobservabilityが大事 構造化ログの重要性 参考: 計測する前に観察せよ ~ Observe. Don't measure for monitoring until you've observed

103.

Rule 5.「データが支配する」 「プログラミングの中心はアルゴリズムではなくデータ構造」 ● ● 「上手く整理されていれば、アルゴリズムは自明となる」 先程のRob Pikeさんの5箇条は後半が特に重要だと思っている Rule 5. Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.

104.

Rule 3., Rule 4. 「高級なアルゴリズムより、素朴なアルゴ リズムと素朴なデータ構造を用いよ」 ● 「高級なアルゴリズムはデータ量が少ない場合は遅いしバグりやすい」 Rule 3. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.) Rule 4. Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures.

105.

Songmuはアルゴリズムが分からぬ ● Webエンジニアはデータ出し入れをやってるだけと揶揄されることも ○ ● データがどこに、どのように保存されているかの意識が重要 ○ ○ ○ ● その通りだし、そこが本懐 データ構造と計算量 ランダムアクセス・シーケンシャルアクセス ストレージ特性やレイテンシ アルゴリズムは自前で書かずに適切なライブラリを使えば良い

106.

データ構造と計算量の理解がとにかく大事 ● ● そのありがたみはデータ量の少ない趣味プログラミングでは最初は分からない コスト感覚を持つことの重要性 ○ ○ ○ ○ ● ツリーは偉大 ○ ○ ● ハッシュテーブルやインデックスアクセス O(1) 線形探索のコスト O(N) ソートのコスト O(N log N) 二分探索のコスト O(log N) 要素の挿入コストと探索コストのバランスに優れている 初学者泣かせだと思う ■ 私も突然リストで使われていたメモリモデルとは異なる概念の絵が出てきて戸惑った 「ほとんどは単純な四則演算」by fujiwara ○ この辺りのコスト感覚が持てれば、単純な四則演算で処理量が見積もれる

107.

例えばRDBMSとKVSの単純な速度比較をしない ● ● データの格納方法が異なる インデックス特性の違い ○ ○ ● データ量 ○ ● 複雑な処理に対してどれくらいデータの一貫性を保てるか 特性を理解して使い分ける ○ ○ ● メモリに乗り切るのか否か トランザクション ○ ● ランダムアクセスが強いのかシーケンシャルアクセスが強いのか RDBMSのインデックスは基本的にはツリーだが他のインデックスも選択できる 基本的にはRDBMSをしっかり使えば大きな問題は起こらない (ちなみに私はRedisを使うのがちょっと得意です) マイクロベンチマークに惑わされない ○ 異なる物をアンフェアな条件で比較しない

108.

整理整頓 Tidy up! ● チリを払うようにコードを日常的に整理整頓する ○ ● 手を入れながらコード全体に対する大局観を養う ○ ● リファクタリング リワークもやりやすく 自然と出来るように ○ ○ ○ 「変な」コードを書かない 適切なデータ構造を選択する テストコードを書く

109.

「無難な書き方」を優先する ● ● マイクロベンチマークや小手先のテクニックに惑わされない 「現行バージョン」ではトリッキーな書き方の方がマイクロベンチマーク で一時的に速くなることもある ○ ○ 下手に飛びつかず、エコシステムの成長に期待する 最終的には自然な書き方の方が速くなるはず

110.

速いコードに頼る ● 速いライブラリ ○ ○ ● 内部ではトリッキーな書き方をしていても、ライブラリ利用者側からは自然なインター フェースになっているもの drop in replacement 速いコードを書ける人 ○ gfxさん, goccyさん

111.

速いコードの落とし穴 ● 速いと言いつつごまかしているケースも少なくない ○ ○ ○ ○ ● 信頼できるライブラリなのかの審美眼も重要 ○ ○ ● 有利なベンチマークを用意している場合 一部処理を端折っている場合 ワーストケースでは遅い場合 無理し過ぎていて、メンテナンス継続が困難な場合 ちゃんとしたコードを書ける人への信頼 「この人が書いてるなら大丈夫だろう」 基本的には標準的だったり広く使われているライブラリを使うのが無難 ○ 優れているかも知れない「オレオレ」ライブラリは淘汰されがち

112.

並列処理とアムダールの法則 ● 並列処理はコンピューティングコストを減らさない ○ ● 基本的には「力技」 速くなるわけではなく「時間が短くなるだけ」 ○ 処理を減らすことや効率化がより大事

113.

資源のフェアユース 特にネットワークアクセス ● ● ● 過剰なアクセスをしない 帯域やAPIのRate Limitの仕様を把握してケアすることの重要性 グレーゾーンを攻めることはサステナブルでは無いことも ○ 今のAI周りのリミットの話でも言えること

114.

改めて「遅くしないこと」とは何か ● ● ● ● ● ● 常日頃からコードベースを「整理整頓」する コードベースを観察して大局観を養う 遅い部分を見付け改善する 適切なデータ構造を選ぶ 無難で自然な書き方を優先する ちゃんと速いライブラリを選んで頼る こういうつまらない当たり前の積み上げが速いコードに繋がる

115.

deckの場合 ● まずは細かい修正をすることで整理整頓 ○ ● ● その中で観察して大局観を養う 絡み合っている部分を解きほぐして、処理の流れを整理 → そこで処理を大幅にまとめられ、劇的な速度向上に繋がった 結局地道な改善がどこかで非連続(に外からは見える)変化に繋がる。何事も

116.

まとめ

117.

ベストスピーカー投票お願いします! ● k1LoW/deck ご利用下さい! ○ ● フィードバックが大歓迎です 速くするのではなく「遅くしない」 ○ ○ ○ ○ ○ 「プログラミングの中心はアルゴリズムではなくデータ構造」 「推測するな計測せよ」 「計測する前に観察せよ」 整理整頓 自然なコードを積み上げる

118.

(宣伝) スポンサー募集 色々OSSを開発・メンテナンスしています。$1のワンショットでも嬉しいの で、活動を支援してくれると嬉しいです。 ● GitHub Sponsor ○ ● https://github.com/sponsors/Songmu ghq handbook ○ ○ https://leanpub.com/ghq-handbook https://zenn.dev/songmu/books/ghq-handbook