TIM Labs

Python簡単実験:集合も内包の方が速い

| コメント(0) | トラックバック(0)
Pythonには複数のデータを扱うのに、リストだけでなく集合(set)もある。
今回は、集合にいっぱい要素を突っ込んだり消したりしたときの速度を調べてみる。
空集合を作り、自然数を1から10,000,000まで1000万個を突っ込んでみた。

>>> import time,os,psutil,sys
>>> pid = psutil.Process(os.getpid())
>>> 
>>> b = set()
>>> sz0 = pid.memory_info().rss
>>> t0 = time.time()
>>> for i in range(1,10000001):
...     b.add(i)
... 
>>> time.time() - t0, pid.memory_info().rss-sz0
(2.310807466506958, 592703488)
2.3秒/1000万個=0.23マイクロ秒/個のペースで追加できている。 そして、メモリは592MB消費したようだ。

同じことを内包を使って実行してみる。
>>> b = set()
>>> sz0 = pid.memory_info().rss
>>> t0 = time.time()
>>> b = {i for i in range(1,10000001)}
>>> time.time() - t0, pid.memory_info().rss-sz0
(0.6817171573638916, 592707584)
0.60秒/1000万個=0.06マイクロ秒/個で、4倍近く高速になっている。
でも1000万個追加するのに、前回のリストのときには0.36秒だったので、集合への追加はリストのアペンドに比べて倍近く時間が掛かっていることが分かる。
集合は、もし同じものがあったら追加されないので、そのあたりの判定も必要になる。

さて、追加だけでなく、削除もやっておこう。
集合の削除メソッドには、remove(x)とdiscard(x)がある。
discardは要素xが存在しなくてもエラーにはならず無視されるだけだが、removeではKeyErrorが発生してしまうので気をつけよう。
>>> sz0 = pid.memory_info().rss
>>> t0 = time.time()
>>> for i in range(10000000,0,-1):
...     b.discard(i)
... 
>>> time.time() - t0, pid.memory_info().rss-sz0
(2.336066484451294, -324263936)
>>> b
set()
消すのは、内包を使わないadd()とほぼ同じ時間かかることが分かった。

ということで、予想通り、集合でも内包を使った方が遥かに高速になるのであった。

トラックバック(0)

トラックバックURL: http://labs.timedia.co.jp/mt/mt-tb.cgi/543

コメントする

このブログ記事について

このページは、fujiが2016年12月24日 00:00に書いたブログ記事です。

ひとつ前のブログ記事は「Python簡単実験:内包で何倍高速になるか」です。

次のブログ記事は「Python簡単実験:集合は大きくなっても小さくならない」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。