96
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python 3.8 では空dictが小さくなる

Last updated at Posted at 2019-03-12

Python 3.7 では {} で作った空 dict よりも、 dict.clear() で作った空 dict の方が省メモリでした。

>>> import sys
>>> d = {}
>>> sys.getsizeof(d)
240
>>> d.clear()
>>> sys.getsizeof(d)
72

これは dict オブジェクトを新規作成するときに最小サイズのハッシュテーブルを確保し初期化するのに対して、 dict.clear() は shared key dict の仕組みを使って空 dict 専用の共有テーブル(書き込み禁止)を利用しているからです。

空の dict の数は無視できないくらいにはあるので、Python 3.8 で新規に dict オブジェクトを作るときも dict.clear() の結果と同じ共有領域を使うようにしました。

>>> import sys
>>> sys.getsizeof({})
64

なお Python 3.7 の dict.clear() のときよりも8バイト小さくなっていますが、これは GC ヘッダを削減した効果で、これも私の功績です(ドヤ)。
参照: https://speakerdeck.com/methane/compact-gc-head

さて、パッチ自体はすごくシンプルなんですが、もちろんコミットするのは簡単ではありません。新規オブジェクトを作ったあとすぐに要素を挿入するケースも多くあり、その場合は最初から専有の、要素を追加できる状態の領域を持っていたほうが高速です。

そのため python/peformance というベンチマークスイートを実行し、性能が悪化しているベンチマークがあったら Linux の perf を駆使してそれが他の環境要因なのか今回の変更によるものなのかどうかを確認するといった地道な作業を裏でしています。

96
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
96
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?