Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPerのための計算量入門 / Basic Knowledge of Time Complexity

PHPerのための計算量入門 / Basic Knowledge of Time Complexity

Time Complexity 101 for PHPer

Ryo Tomidokoro

March 30, 2019
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Technology

Transcript

  1. PHPerのための計算量入門
    Ryo Tomidokoro
    PHPerKaigi 2019/3/30
    @hanhan1978

    View Slide

  2. よくあるコード例から
    計算量を理解してみよう

    View Slide

  3. 例題
    とあるウェブサービスを運営する会社の営業社員が会員
    データの分析をするためのCSVファイルを作ります。
    全ユーザのデータをDatabaseから取得して、各種付帯情
    報を追加してCSVファイルを作成します。

    View Slide

  4. コード例

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. この問題をどのように検出する?
    なるべく勘や経験に頼りたくはないが、何か良い方法は
    あるだろうか?

    View Slide

  9. 問題を検出する方法

    View Slide

  10. ◎負荷試験
    人材や納期、品質向上への理解があるのであれば、本番
    相当以上のデータ量を用意した負荷試験を行えば、確実に
    検出することが可能
    今までのエンジニア人生で、CIに負荷試験が組み込まれ
    ているのを見たことは稀…

    View Slide

  11. 静的解析
    PHPStan, PHPMD等、試してみたが流石に計算量の問題点
    は検出できない。

    View Slide

  12. ▲経験
    好きなアプローチではないが、現状もっとも低コストで
    現実的に実行できる対策はこれになってしまう。研修や教
    育によって計算量に対して、意識を向けてもらうようにす
    る。

    View Slide

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

    View Slide

  14. 計算量とは?

    View Slide

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

    View Slide

  16. 時間計算量の測り方

    View Slide

  17. 単純な掛け算関数

    View Slide

  18. 単純な掛け算関数

    View Slide

  19. 単純な掛け算関数

    View Slide

  20. すべてのアルゴリズムで厳密な時間計算量を
    算出するのは大変です。
    そこで、時間計算量の世界には便利な記法が
    あります。

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. コード例

    View Slide

  26. コード例

    View Slide

  27. コード例

    View Slide

  28. 計算量オーダーを下げる

    View Slide

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

    View Slide

  30. 改善例

    View Slide

  31. 改善例

    View Slide

  32. 処理時間を再計測

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  36. in_arrayは遅いので、array_key_existsに書き換えて!
    悪い指摘の仕方

    View Slide

  37. このプログラムが処理するデータ量が3万件です。アル
    ゴリズムの計算量がO(N^2)なので、処理時間に懸念があり
    ます。念の為、負荷試験を追加で行ってもらって良いで
    しょうか?
    良い指摘の仕方

    View Slide

  38. おまけ

    View Slide

  39. 配列操作関数の計算量
    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

    View Slide

  40. Redisのドキュメント

    View Slide

  41. 参考図書
    数学ガール4 乱択アルゴリズム (結城 浩)
    みんなのコンピューターサイエンス (Wladston Ferreira Filho)
    アルゴリズムとデータ構造 (近藤 嘉雪)

    View Slide

  42. Thanks!!
    @hanhan1978
    https://blog.hanhans.net
    Ryo Tomidokoro

    View Slide