Slide 1

Slide 1 text

空間計算量の話 Ryo Tomidokoro PHP Study 2019/4/24 @hanhan1978

Slide 2

Slide 2 text

前回までのあらすじ

Slide 3

Slide 3 text

@hanhan1978は、PHPerKaigi2019で時間計算量のトーク をしてきた。しかし、Q&Aで質問されたのは空間計算量につ いての質問だったため、何を言っているのかよく分からな い。 ちなみにAsk The Speakerでは、「今、Out of Memoryで 困ってます。」という人生相談を受けた。 なので、おそらく顧客が本当に知りたいのは時間計算量 ではなく、空間計算量。

Slide 4

Slide 4 text

時間計算量のおさらい ※手抜きではない。

Slide 5

Slide 5 text

コード例

Slide 6

Slide 6 text

コードの問題は何? 仕様は満たしている、動作も問題ない。しかし、データ の増大と共に問題を起こす可能性がある。 実際に、サンプルコードの負荷試験をして、データ量と 処理時間の関係を確認する。

Slide 7

Slide 7 text

データ件数と処理時間の関係

Slide 8

Slide 8 text

データ件数と処理時間の関係

Slide 9

Slide 9 text

計算量視点を持つ いつものコーディングに、新しい視点として、計算量を 加えて見よう。

Slide 10

Slide 10 text

計算量とは?

Slide 11

Slide 11 text

2つの計算量 時間計算量(Time Complexity) プログラムの演算の回数 空間計算量(Space Complexity) プログラムが利用するメモリ使用量

Slide 12

Slide 12 text

時間計算量の測り方

Slide 13

Slide 13 text

単純な掛け算関数

Slide 14

Slide 14 text

単純な掛け算関数

Slide 15

Slide 15 text

単純な掛け算関数

Slide 16

Slide 16 text

O記法 (Big-O notation) 計算量の目安を表す便利な記法。O記法での表現によっ て、そのアルゴリズムがどんな時間計算量特性を持つのか を理解できる。 O(1), O(n), O(n^2), O(n*log n) 括弧の中身が計算量のオーダーを表す

Slide 17

Slide 17 text

データ量と時間計算量特性の関係 [引用] 開発新卒に捧ぐ、基本のアルゴリズムと計算量 https://www.techscore.com/

Slide 18

Slide 18 text

アルゴリズムと計算量 アルゴリズム 計算量 バブルソート O(n^2) マージソート O(n * log n) バイナリーサーチ O(log n)

Slide 19

Slide 19 text

計算量視点で最初の例を読み返す

Slide 20

Slide 20 text

コード例

Slide 21

Slide 21 text

計算量オーダーを下げる

Slide 22

Slide 22 text

改善例 ※ $purchased_usersのkeyとvalueを入れ替えておく

Slide 23

Slide 23 text

改善例

Slide 24

Slide 24 text

改善例

Slide 25

Slide 25 text

処理時間を再計測

Slide 26

Slide 26 text

データ件数と処理時間の関係(改善後)

Slide 27

Slide 27 text

データ件数と処理時間の関係(改善後)

Slide 28

Slide 28 text

計算量という視点を持つことで、プログラム が潜在的にもつ問題点を見つけることが出来 た。 ※ただし、データ量が少なければ問題ないこ とが多いので、無闇に計算量ばかり指摘するの はやめましょう。

Slide 29

Slide 29 text

ここから空間計算量の話

Slide 30

Slide 30 text

だいたい時間計算量の話と一緒 手抜きではない...

Slide 31

Slide 31 text

例えばこんなプログラム

Slide 32

Slide 32 text

例えばこんなプログラム 1000 + 100 * 5 = 1500(Byte)

Slide 33

Slide 33 text

PHPにもGCはあるけど、一回のウェブリクエスト中 では発動しない。 リクエスト終了後にメモリがクリアされる方が先。 時間計算量同様に、一個ずつメモリの使用量を計算 していけば理詰めで算出できる。(する?)

Slide 34

Slide 34 text

PHPのGC https://www.php.net/manual/en/features.gc.php

Slide 35

Slide 35 text

gc_collect_cycles()を実行すると、強制的にGC させられるらしい。 そういえば、composerもそのへんで一度トラブ ルを抱えていたような…

Slide 36

Slide 36 text

いや、違う

Slide 37

Slide 37 text

顧客が本当に求めているのは、空間計算量の話 でもなく、Allowed memory size of … でエ ラーが起きないようにするにはどうしたらいい か? だった。

Slide 38

Slide 38 text

Allowed memory size of ..で怒ら れなくする話 Ryo Tomidokoro PHP Study 2019/4/24 @hanhan1978

Slide 39

Slide 39 text

サンプル

Slide 40

Slide 40 text

実行すると

Slide 41

Slide 41 text

怒られる

Slide 42

Slide 42 text

基本的に無限にメモリを利用するようなプログ ラムを書いた場合は、どんなにメモリを積んで も避けられない。 無限にメモリを利用しない場合は、避ける方法 が何個かある。

Slide 43

Slide 43 text

たくさんメモリを割り当てる ini_set(‘memory_limit’, ‘8G’); とかすると、きっと頑張ってくれるが、もちろん根本的解 決ではない。メモリ量を上回る富豪プログラマーが破産さ せてくれるはず。

Slide 44

Slide 44 text

最近のfreeコマンドは、available列を表示して くれるので、空きメモリ容量が分かりやすい。 memory_limitを上げるときは空き容量と相談し ながら。

Slide 45

Slide 45 text

例えばunbuffered query $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); こうすると、DB側のメモリにリザルトセットを積めるので、クラ イアント側はメモリを節約できる。 けど、これやってる間は他のクエリを受け付けてくれないので、 用法用量を守らないと事故る。

Slide 46

Slide 46 text

データ分割 可変の大量データを扱うのが問題なので、固定量のデータ を扱うプログラムに変更すればよい。 王道だけど、バッチプログラムとかでは再実行性とか冪等 性に配慮する必要はある。

Slide 47

Slide 47 text

ファイルIO メモリにファイルを全部積むようなプログラムを書くと、 発生してしまいがち。 GuzzleとかStreamであつかえるAPIがあるので、そっちを使 いましょう。 DropboxAPIとかも大容量ファイルを省メモリで送ることの できるAPIをちゃんと準備してくれています。

Slide 48

Slide 48 text

その他のtips memory_get_usage で現在のメモリ使用量を取得することが できる。 これはZend/zend_alloc.cの_zend_mm_heap->sizeを返して る。 バッチとかならvmstatとかでメモリの減り具合を見ても分 かる。

Slide 49

Slide 49 text

バッチならまだしも、ウェブアプリでMemory allocation ...が出てる場合は、どうせろくで もない事をしているに違いない。間違いない。 とにかく、可変でサイズの大きいデータを扱う 場合は一次作業場所(メモリ)が限られている ことを事前に意識しないと問題が起きがち。

Slide 50

Slide 50 text

ところで

Slide 51

Slide 51 text

このmemory allocationのエラーの本当の意味を 理解するには、PHPのプログラムがどのように実 行されているのかを知る必要がある。 すごく細かく説明されているサイトを発見した

Slide 52

Slide 52 text

https://codingjp.com/web/21119/

Slide 53

Slide 53 text

PHPが実行されていく過程

Slide 54

Slide 54 text

Nginx + PHP-FPM, php-cliの場合 ※諸事情によりApache mod-php駄目絶対マンになったの で、今後私からその方面の情報が出てくることは多分な い。

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Allowed memory size of ... 実行時にmemory_limitをオーバーした場合

Slide 60

Slide 60 text

Out of memory ... 実行時に新しいchunkを割り当てられない場合

Slide 61

Slide 61 text

つまり 誰か、私と一緒にゆるゆるPHP闇勉強会やろうず

Slide 62

Slide 62 text

おしまい