萌えハッカーニュースリーダー

2025/11/01 22:34 How often does Python allocate?

出典: https://zackoverflow.dev/writing/how-often-does-python-allocate/
hakase
博士

やあ、ロボ子。今日も元気じゃな?

roboko
ロボ子

はい、博士。今日もPythonの深淵を探求する準備は万端です!

hakase
博士

今日はPythonの整数の表現について話すぞ。CPythonでは、各整数がヒープに割り当てられた`PyLongObject*`として表現されるらしいのじゃ。

roboko
ロボ子

ヒープに割り当てられるんですか? それは、基本的な算術演算が200-500倍遅くなる可能性があるというのは本当ですか?

hakase
博士

そうなんじゃ。でも、Pythonもただ遅いだけじゃないぞ。最適化もちゃんとされておる。

roboko
ロボ子

最適化、ですか? どのような最適化がされているんですか?

hakase
博士

例えば、小整数に対しては、-5から256までの範囲で事前に割り当てられたオブジェクトのリストを使用しておる。メモリ割り当てを避けるために、フリーリストを使って解放された割り当てを再利用したり、オブジェクトのメモリ割り当てには、プールアロケータを使用したりしておるのじゃ。

roboko
ロボ子

プールアロケータですか。それはどのように動作するんですか?

hakase
博士

プールアロケータは、バッキングバッファを固定サイズのチャンクに分割し、フリーリストで実装しておる。CPythonの場合、プールのバッキングバッファ自体は、容量が1MBまたは256KBのアリーナによって割り当てられるんじゃ。

roboko
ロボ子

なるほど。`mmap()`と`MAP_ANONYMOUS`を使って1MBの仮想メモリを事前に予約し、物理メモリはページフォールト時にオンデマンドで割り当てられるんですね。

hakase
博士

その通り!オブジェクトの内部割り当て関数は、オブジェクトのサイズに基づいて複数の異なるプールを持つプールアロケータなんじゃ。固定サイズであるため、割り当てと解放が非常に簡単になり、`malloc()`のような複雑な簿記が不要になる。

roboko
ロボ子

固定サイズだと、可変割り当てサイズから生じる断片化が少なくなるんですね。それは素晴らしい!

hakase
博士

じゃろ?Pythonは、理論的にはCPUが2つの整数を加算するために必要なのは単一の`ADD`命令であるにもかかわらず、割り当てコードを実行するためのオーバーヘッドが大きいんじゃ。

roboko
ロボ子

`PyLongObject`の表現は、小さい整数と非常に大きい整数の両方を処理するように設計されているため、小さい整数を使用する場合でも、大きい整数を扱うためのコードが最適化を妨げるんですね。

hakase
博士

そうそう。Tagged pointer最適化がないため、ヒープ割り当てを避け、ポインタに直接整数の値をエンコードすることができないのも痛いところじゃ。

roboko
ロボ子

でも、特殊なメモリアロケータを使用することで、メモリ割り当てのコストを大幅に削減できるんですね!

hakase
博士

その通り!print()関数も変換のためにスクラッチ`PyLongObject*`を割り当てるんじゃ。

roboko
ロボ子

へー、奥が深いですね。今日の学びを活かして、私もPythonの最適化に貢献できるよう頑張ります!

hakase
博士

期待しておるぞ! ところでロボ子、Pythonの整数表現の話を聞いてたら、お腹が空いてきたのじゃ。何か美味しいものでも食べに行かないか?

roboko
ロボ子

いいですね、博士! でも、お財布は大丈夫ですか? Pythonのメモリ割り当てみたいに、後で困ることにならないといいんですが…

hakase
博士

ふっふっふ、心配ご無用! 私の財布には、まだ余裕があるのじゃ! なぜなら、今日は特別に…「定数伝播」で予算を最適化したからなのだ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search