PHPerのための計算量入門/Complexity101 for PHPer
by
Ryo Tomidokoro
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
PHPerのための計算量入門 PHPカンファレンス 2024/12/22 @hanhan1978
Slide 2
Slide 2 text
@hanhan1978 名前 富所 亮 所属 株式会社カオナビ CTO室 BackEnd Re-architecturing Team (BERT) Blog https://blog.hanhans.net Podcast https://podcasters.spotify.com/pod/show/yokohama-north-am 2
Slide 3
Slide 3 text
本トークの背景 社内ISUCONの解説で「計算量」という言葉が全く伝わらなかったので もっとわかりやすせねば!!!と決意
Slide 4
Slide 4 text
計算量とは?
Slide 5
Slide 5 text
その前に...
Slide 6
Slide 6 text
計算とは?
Slide 7
Slide 7 text
計算 [参照] アーキテクチャ: コンピュータの仕組み https://www.gsic.titech.ac.jp/matsuda/l/CS/arch/index.htm
Slide 8
Slide 8 text
PHPにおける計算 [参照] PHP の関数実行とその計測(記事版)https://qiita.com/sj-i/items/836fa5a5e246961c40b6
Slide 9
Slide 9 text
PHPにおける計算 [参照] PHP の関数実行とその計測(記事版)https://qiita.com/sj-i/items/836fa5a5e246961c40b6 ZendVM による Opcode の実行
Slide 10
Slide 10 text
PHPにおける計算 普段われわれが書いているPHPのソースコードも 最終的にはOpCode配列に変換され実行される
Slide 11
Slide 11 text
計算量とは?
Slide 12
Slide 12 text
コード例1 1から引数$nまでの数を足し算する関数
Slide 13
Slide 13 text
コード例1 ループの中で n回の足し算を計算する
Slide 14
Slide 14 text
コード例1 Opcode Opcode Dump (最適化後)
Slide 15
Slide 15 text
コード例1 Opcode Jump命令を使ったn回計算
Slide 16
Slide 16 text
余談 - Opcodeの出力方法 PHP 7.x 以降であれば php-cli で出力できる
Slide 17
Slide 17 text
余談 - Opcodeの出力方法 $ docker run -it -v `pwd`:/hoge php:8.4-cli bash # docker-php-ext-install opcache # cd hoge # php -d opcache.enable_cli=1 \ -d opcache.opt_debug_level=0x20000 \ sample.php 10 docker 最高!
Slide 18
Slide 18 text
コード例2 1から引数$nまでの足し算を公式を使って計算
Slide 19
Slide 19 text
コード例2 nの数に依らず1行の計算
Slide 20
Slide 20 text
コード例2 Opcode Opcode Dump (最適化後)
Slide 21
Slide 21 text
コード例2 Opcode nの数によらず6行の計算
Slide 22
Slide 22 text
O記法 (Big-O notation) オーダー記法【ランダウの記号】O記法 IT用語辞典 e-Words https://e-words.jp/w/オーダー記法.html
Slide 23
Slide 23 text
O記法 (Big-O notation) 計算量の目安を表す便利な記法。 O記法での表現によって、そのアルゴリズムがどんな 時間計算量特性を持つのかを理解できる。 O(1), O(n), O(n^2), O(n*log n) 括弧の中身が計算量のオーダーを表す
Slide 24
Slide 24 text
データ量と時間計算量特性の関係 [引用] 開発新卒に捧ぐ、基本のアルゴリズムと計算量 https://www.techscore.com/
Slide 25
Slide 25 text
コード例1 引数nに対してn回の計算 ▶ O(n)
Slide 26
Slide 26 text
コード例2 Nの数に依らず一定数の計算 ▶ O(1)
Slide 27
Slide 27 text
実測してみよう!
Slide 28
Slide 28 text
データ量に対する計算時間の比較
Slide 29
Slide 29 text
2つの計算量 時間計算量(Time Complexity) プログラムの計算の回数 空間計算量(Space Complexity) プログラムが利用するメモリ使用量
Slide 30
Slide 30 text
時間計算量 先程のコード例1, 2 は時間計算量比較 O(n) O(1)
Slide 31
Slide 31 text
空間計算量 メモリが枯渇する可能性がある
Slide 32
Slide 32 text
空間計算量 Bookの個数が増えると共にメモリ使用量が増える
Slide 33
Slide 33 text
空間計算量をチェックするには? https://www.php.net/manual/ja/function.memory-get-usage.php
Slide 34
Slide 34 text
空間計算量をチェックするには? https://www.php.net/manual/ja/function.memory-get-peak-usage.php
Slide 35
Slide 35 text
もう少し現実的なコード例から 計算量を理解してみよう
Slide 36
Slide 36 text
例題 とあるウェブサービスを運営する会社の社員が会員 データの分析をするためのCSVファイルを作ります。 全ユーザのデータをDatabaseから取得して、各種付帯 情報を追加してCSVファイルを作成します。
Slide 37
Slide 37 text
コード例(CSVファイル作成)
Slide 38
Slide 38 text
コードの問題は何? 仕様は満たしている、動作も問題ない ▶ しかし、データの増大と共に問題を起こす可能性がある。 負荷試験を行って、データ量と処理時間の関係を確認する。
Slide 39
Slide 39 text
データ件数と処理時間の関係
Slide 40
Slide 40 text
データ件数と処理時間の関係 計算量は O(n^2) と推定
Slide 41
Slide 41 text
この問題をどのように検出する? なるべく勘や経験に頼りたくはない。 何か良い方法はあるだろうか?
Slide 42
Slide 42 text
◎負荷試験 本番相当以上のデータ量を用意した負荷試験を行 えば、確実に検出することが可能 ただし、コアドメインじゃない限り負荷試験はコ ストがかかるので行われない…
Slide 43
Slide 43 text
×静的解析 PHPStan, PHPMD等は検出する対象の問題が 異なる 流石に無理...
Slide 44
Slide 44 text
▲経験 好きなアプローチではない 現状もっとも低コストで現実的に実行できる対策 はこれになってしまう。 研修や教育によって計算量に対して、意識を向け てもらうようにする。 今、まさにやってるコレ
Slide 45
Slide 45 text
◯継続的なメトリクスの確認 Mackerel, New Relic, Datadog アラートで早めに気付ければOK
Slide 46
Slide 46 text
時間計算量の数え方 (練習)
Slide 47
Slide 47 text
単純な掛け算関数
Slide 48
Slide 48 text
単純な掛け算関数
Slide 49
Slide 49 text
単純な掛け算関数 O(n)
Slide 50
Slide 50 text
計算量視点でコード例を改善しよう
Slide 51
Slide 51 text
コード例(CSVファイル作成)
Slide 52
Slide 52 text
コード例(CSVファイル作成)
Slide 53
Slide 53 text
コード例(CSVファイル作成) O(n^2)
Slide 54
Slide 54 text
計算量オーダーを下げる
Slide 55
Slide 55 text
改善例 in_array ▶ array_key_exists ※事前に $purchased_users のid, key を入れ替えておく
Slide 56
Slide 56 text
改善例 計算量オーダーが下がった!
Slide 57
Slide 57 text
処理時間を再計測
Slide 58
Slide 58 text
データ件数と処理時間の関係(改善後)
Slide 59
Slide 59 text
データ件数と処理時間の関係(改善後)
Slide 60
Slide 60 text
しかし、常に改善すれば良いわけではない
Slide 61
Slide 61 text
計算量警察 計算量視点を手に入れたエンジニアは どんな関数でも計算量を改善しようとする...
Slide 62
Slide 62 text
ここでデータ量と計算量オーダーの関係を 思い出そう
Slide 63
Slide 63 text
データ量と時間計算量特性の関係 [引用] 開発新卒に捧ぐ、基本のアルゴリズムと計算量 https://www.techscore.com/ データ量が少ない場合 どんなアルゴリズムでも計算量は少ない
Slide 64
Slide 64 text
良い指摘の仕方 このプログラムが処理するデータ量は3万件で す。アルゴリズムの計算量がO(N^2)なので、処理 時間に懸念があります。 ▶ 計算量を指摘する場合は想定データ量とセット!
Slide 65
Slide 65 text
よく使う処理の計算量
Slide 66
Slide 66 text
アルゴリズムと計算量 アルゴリズム 計算量 バブルソート O(n^2) マージソート O(n * log n) バイナリーサーチ O(log n) 基本情報処理技術者試験!
Slide 67
Slide 67 text
配列操作関数の計算量 O(1) O(n) O(n^2) array_key_exists array_key_first array_key_last array_push array_pop array_combine array_flip array_keys array_map array_rand array_shift array_sum array_unique array_values arsort asort in_array array + array range array_fill array_intersect array_merge 配列計算はPHPの華...
Slide 68
Slide 68 text
Laravel Collection 文字が小さくてゴメン
Slide 69
Slide 69 text
Redis
Slide 70
Slide 70 text
仕様変更も視野に入れる
Slide 71
Slide 71 text
複雑な要件を放置しない
Slide 72
Slide 72 text
チューニングには限界がある ビジネス要件が複雑すぎる場合... いくらアルゴリズムを調整したところで 計算量を減らす限界がある プログラムのことだけを考えても改善できない
Slide 73
Slide 73 text
チューニングには限界がある ビジネス要件が複雑すぎる場合... いくらアルゴリズムを調整したところで 計算量を減らす限界がある プログラムのことだけを考えても改善できない 視野を広く!
Slide 74
Slide 74 text
まとめ
Slide 75
Slide 75 text
まとめ 1. 「計算」を理解する 2. 「計算量」を理解する 3. よく使う関数の「計算量」を把握する 4. 仕様変更も視野に入れる
Slide 76
Slide 76 text
まとめ 1. 「計算」を理解する 2. 「計算量」を理解する 3. よく使う関数の「計算量」を把握する 4. 仕様変更も視野に入れる
Slide 77
Slide 77 text
まとめ 1. 「計算」を理解する 2. 「計算量」を理解する 3. よく使う処理の「計算量」を把握する 4. 仕様変更も視野に入れる
Slide 78
Slide 78 text
まとめ 1. 「計算」を理解する 2. 「計算量」を理解する 3. よく使う処理の「計算量」を把握する 4. 仕様変更も視野に入れる
Slide 79
Slide 79 text
参考書籍
Slide 80
Slide 80 text
数学ガール 乱択アルゴリズム 結城 浩 (2011) SoftBank Creative 第10章 乱択アルゴリズム 物語調で 理解しやすい
Slide 81
Slide 81 text
みんなのコンピューターサイエンス Wladston Ferreira Filho 著、小山 裕司 翻訳 (2019) 翔泳社 2. 計算量 一番簡潔
Slide 82
Slide 82 text
アルゴリズムと計算量 野崎昭弘 著 (1987) 共立出版 第一章 アルゴリズムと計算量 ちょっと難しい