Laravel Collectionの計算量を調べてみた

こんにちは、エンジニアの @hanhan1978です。

2018/09/26(水)GMO Yoursにて開催された第130回 PHP勉強会@東京 - PHP勉強会@東京 | Doorkeeperにおきまして、「Laravel Collectionの計算量を調べてみた」というタイトルでLTしてきました。

f:id:hanhan1978:20180927143825j:plain

Laravel Collectionとは?

laravel.com

公式で用意されている配列のラッパークラスです。Webサイトで頻繁に利用するような便利なメソッドが多数用意されていて、データベース検索結果の加工・表示が簡単に出来るようになっています。

登壇内容

Speaker Deckにアップしてあります。

speakerdeck.com

計算量一覧

スライド内に計算量の一覧を写真で貼り付けたのですが、文字が潰れて判読不能でした。 というわけで、下記に改めて一覧でまとめました。

なお、調査対象のLaravelバージョンは5.7です。
https://laravel.com/docs/5.7/collections#available-methods

メソッド名 計算量 メソッド名 計算量
all O(1) nth O(n)
average O(n) only O(n)
avg O(n) pad O(1)
chunk O(n) partition O(n)
collapse O(n2) pipe -
combine O(n) pluck O(n)
concat O(n) pop O(1)
contains O(n) prepend O(n)
containsStrict O(n) pull O(n)
count O(1) push O(1)
crossJoin O(n3) put O(1)
dd O(n) random O(n)
diff O(nt) reduce O(n)
diffAssoc O(nt) reject O(n)
diffKeys O(n) reverse O(n)
dump O(n) search O(n)
each O(n) shift O(n)
eachSpread O(n) shuffle O(n)
every O(n) slice O(n)
except O(n) sort O(n)
filter O(n) sortBy O(n)
first O(1) sortByDesc O(n)
firstWhere O(n) sortKeys O(n)
flatMap O(n2) sortKeysDesc O(n)
flatten O(n2) splice O(1) or O(n)
flip O(n) split O(n)
forget O(n) sum O(n)
forPage O(n) take O(1) or O(n)
get O(1) or O(n) tap -
groupBy O(n2) times O(n)
has O(n) toArray O(n)
implode O(n) toJson O(n)
intersect O(n2) transform O(n)
intersectByKeys O(n) union O(n)
isEmpty O(1) unique O(n)
isNotEmpty O(1) uniqueStrict O(n)
keyBy O(n) unless -
keys O(n) unwrap O(1)
last O(n) values O(n)
macro - when -
make - where O(n)
map O(n) whereStrict O(n)
mapInto O(n) whereIn O(n)
mapSpread O(n) whereInStrict O(n)
mapToGroups O(n) whereInstanceOf O(n)
mapWithKeys O(n) whereNotIn O(n)
max O(n) whereNotInStrict O(n)
median O(n) wrap O(1)
merge O(n) zip O(n)
min O(n)
mode O(n)

参考文献

御本人に反応して頂けてすごく嬉しかったです。プログラミングでご飯を食べていくなら、本当にオススメですので是非!

その他補足

色々なご意見頂けたのですが、計算量を気にされている方は Laravel Collectionの中でも基本的なループ処理しか使っていないということでした。 実際に自分も仕事においては、今回注意喚起したような計算量が多いメソッド(diff, collapse,flatMap等)は未使用でした。

ただし、実例でも示したようにO(n)オーダーでもループ内で組み合わせて使うことで、計算量爆発を起こすコードを簡単に記述することができます。1000件程度のCollectionでも充分な速度劣化を起こすことが出来ます。

計算量の多いメソッドに注意しつつ、今後もデータ量の増加を見込んだ上で効率の良いプログラミングを目指したいところです。