8月7日、LWN.netが「Python performance myths and fairy tales」と題した記事を公開した。この記事では、Pythonの性能に関する「神話」とも言える誤解を批判的に検証し、現実の制約と今後の可能性について詳しく紹介されている。

以下に、その内容をかいつまんで紹介する。詳しくは原文を参照していただきたい。
Pythonは本当に「遅い」のか?
記事は、EuroPython 2025において、PyPyの開発者であり長年Python性能の向上に取り組んできたAntonio Cuni氏による講演内容を中心に構成されている。Cuni氏は、Pythonの性能について多くの「神話」が存在するとし、それらを一つずつ検証していった。
誤解その1:「Pythonは遅くない」
会場で「Pythonは遅いと思うか」と尋ねたところ、多くの聴衆が手を挙げた。この反応は、PyCon Italyでの講演とは対照的だったという。Cuni氏は、「Pythonは一部の用途には十分に高速だが、それはPythonを使っている全ての用途には当てはまらない」と指摘する。
例えば、計算量の多い処理ではCythonやNumbaといった最適化手法が使われることが多い。しかし、そうした努力もアムダールの法則の壁にぶつかる。「ホットパスをC++やRustで書き直せばいい」という考えも、部分的にしか正しくない。高速化には限界があるのだ。
※アムダールの法則(Amdahl's Law)とは、コンピュータシステムの性能改善において、一部をどれだけ高速化しても、全体の性能向上には限界があることを示す法則である。1967年にコンピュータ科学者のジーン・アムダール(Gene Amdahl)によって提唱された。
誤解その2:「Pythonはインタプリタだから遅い」
Cuni氏は、Pythonが遅い理由は「インタプリタであること」よりも「言語仕様のダイナミズム」にあると説明する。
p.x * 2
この一見シンプルな式も、Pythonでは多数の手続き(属性アクセス、ボクシング、アンボクシング、型チェックなど)を経る必要がある。これらはPythonがインタプリタであるかどうかとは無関係で、言語の仕様そのものに起因する。
静的型は性能向上に寄与するか?
def add(x: int, y: int) -> int:
return x + y
このような型注釈付きコードでも、実行時に型は強制されず、以下のようなコードも合法である:
print(add('hello ', 'world')) # type: ignore
そのため、「静的型注釈があるからコンパイラが高速化できる」というのは幻想であるとCuni氏は語る。
JITですべて解決するわけではない
Pythonは現在、単純で動的な言語から、高速で動的な言語へと進化しようとしている。たとえばCPython JITプロジェクトなどはその例だ。
しかし、JITは実装が複雑で、最適化を狙って書かれたコードでさえ、期待通りに最適化されないことがある。PyPyでも最適化を妨げる何気ないコード変更で10倍遅くなるケースがあるという。
動的であることの代償
次のようなコードがすべて「合法」であるのがPythonの特徴だ。
import random
class Evil:
if random.random() > 0.5:
def hello(self):
print("hello world")
Evil().hello()
半分の確率でメソッドが存在せず、エラーになる。これを最適化することは非常に困難である。
また、__new__
メソッドを使えば、実体がクラスと異なるインスタンスを返すことさえ可能だ。
class Person:
def __new__(cls, name, age):
if age < 18:
return object.__new__(Student)
return object.__new__(Person)
静的な型推論にとっては悪夢のような構造である。
抽象化のコスト
抽象化にもコストがある。以下のようなシンプルな関数も、構造を改善するごとにパフォーマンスが低下する:
@dataclass
class Point:
x: float
y: float
def fn(p):
return p.x**2 * p.y + 10
def algo(items: list[Point]):
res = 0
for p in items:
res += fn(p)
return
これは「Python内での抽象化(Python-to-Python abstraction)」であり、コストが顕著になる。
また「PythonからCへの抽象化(Python-to-C)」も、ボクシング/アンボクシングによって性能が下がることがある。PyPyではむしろCコードを排除することで高速化に成功したケースもあるという。
パフォーマンスの真のボトルネックはメモリ管理
Pythonはメモリ配置がキャッシュ非効率的である。以下のような構造でも:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = [Person('Alice', 16), Person('Bob', 21)]
オブジェクトはメモリ内に分散して配置され、キャッシュミスが多発する。これに対処するにはJITでは不十分で、「セマンティクスを変える必要がある」とCuni氏は述べた。
「それでも希望はある」——SPyプロジェクト
講演の最後に、Cuni氏は希望として「SPy(Static Python)」というプロジェクトを紹介した。これは互換性を保ちつつ、静的で高速なPythonを目指す試みである。
このデモでは、NumPyで2fpsしか出なかったリアルタイムエッジ検出が、SPyを使うと60fpsで動作することが示された。
Pythonの持つ「動的な魅力」は同時にパフォーマンスの障壁にもなっている。互換性を維持しながら高速化を実現するには、現状の言語仕様そのものの見直しが必要だというCuni氏の指摘は、今後のPythonの方向性に大きな示唆を与える内容である。
詳細はPython performance myths and fairy talesを参照していただきたい。