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) 共立出版 第一章 アルゴリズムと計算量 ちょっと難しい