Laravel Verison 10 と PHP8.2 で調査しなおしました。
@hanhan1978Laravel Collectionの計算量を調べてみた2023年度版(非公式)PHPカンファレンス福岡 前夜祭2023/06/23
View Slide
@hanhan1978● 富所 亮● 所属株式会社カオナビBackEnd Re-architecturing Team (BERT)● 職業バックエンドエンジニア● ブログhttps://blog.hanhans.net● Yokohama North AMhttps://anchor.fm/yokohama-north-am2
2018年に発表していた内容を最新バージョンでやってみました
これの2023年版Laravel Version 5.7
計算量についておさらい本日は時間計算量を扱います
https://speakerdeck.com/hanhan1978/basic-knowledge-of-space-complexity空間計算量については、こっちのスライドを参照
例えばレビューしている時
「この処理遅そう」これだと分かりにくい。処理の時間的速度を共通知識で伝えたい
英語だと Time Complexity時間複雑性プログラムの処理にどれくらい時間がかかるかを数学的に扱う
O記法O(1)O(log n)O(n)O(n * log n)O(n^2)プログラムの時間的計算量を表す
O記法データ量が増加した場合の処理時間の増加傾向が分かる
http://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量/データ量と計算量[グラフ引用] 開発新卒に捧ぐ、基本のアルゴリズムと計算量
計算量とアルゴリズムアルゴリズム 計算量バブルソート O(n^2)マージソート O(n log n)バイナリサーチ O(log n)アルゴリズムによって計算量が異なる
さらに詳しく知りたい人数学ガール4 乱択アルゴリズム2章と6章を読むべし
Laravel Collection各メソッドの計算量
細かすぎて見えない!
share しておきますhttps://docs.google.com/spreadsheets/d/1RbHo6huSTBkdSpWoCMRyS0E5bBvaYJdWUO3NHLVFfYg/edit?usp=sharing
雑にまとめると
• ほとんど O(n) O(1)• O(n^2) 以上が30個
要注意メソッド• crossJoin O(n^t)• diff系 O(n^t)• flat系 O(n^t)• flatten系 O(n^2)• merge系 O(n^2)• intersect系 O(n^2)
実測してみた
where - O(n)
count - O(1)
shift - O(n^2)
計算量が分かったとして何か良いことあるのか?
知らないと悪いことが起きる
実際にあったかもしれない計算量が問題になったコード例※実話を元にしたフィクション
全件取得ページングのために全件ループで回す例1
全件取得ページングのために全件ループで回す例1ページの後半に行けば行くほどループが回って遅くなる O(n)
例2第1ループで全件回す O(n)第2ループも全件回す O(n)
合わせ技 O(n^2)O(n)を入れ子にすればパワーアップ例2第1ループで全件回す O(n)第2ループも全件回す O(n)
例2第1ループで全件回す O(n)第2ループも全件回す O(n)第一引数は最大で数百件程度だったが第二引数のデータ数が成長していくと…
事前に検知できないか?
実は例1・2のコードは単体テスト -> 通過受け入れテスト -> 通過通過してしまっていた…
データが増えないと問題にならない
http://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量/データ量と計算量(再掲)[グラフ引用] 開発新卒に捧ぐ、基本のアルゴリズムと計算量
負荷テストコードレビュー事前検出可能な砦
負荷テストデータ量が莫大になることがわかっているプロダクトは行っている。通常のプロダクトだとあんまりやってるの見たこと無い。
コードレビューレビュアーのスキルや経験に依存事前に計算量についてチーム内で勉強会とかしてれば指摘&修正は簡単だと思う
監視ツールで、処理時間のメトリクスを見て理詰めで処理時間の遅い部分を特定できればまあ、及第点だと思う。最悪見逃しても
まとめ
● 計算量はデータのサイジングが肝● データ量がすくないなら、問題にならない● 過剰品質には気をつけよう!バランスの良い判断をしよう
おまけ
計算量が一目瞭然
データの集まりを扱うプログラムは計算量を確認しましょう
random8.2 で Random が改善
たまに、Laravel側の実装変更で思いっきり劣化することがあるので注意!uniqueとか....
おしまい