Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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() の結果と同じ共有領域を使うようにしました。

https://github.com/python/cpython/pull/1080

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

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

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

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

klab
モバイルオンラインゲーム、その他スマートフォン関連サービス、及びサーバーインフラ開発・運用
http://www.klab.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away