python / python/cpython

`typing`: one `None`-valued member makes `isinstance()` on a `runtime_checkable` Protocol O(N) per call

オープン
#156,413 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

performance stdlib topic-typing type-feature
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

A class satisfying a @runtime_checkable Protocol with any class attribute set to None still passes isinstance(), but is orders of magnitude slower, scaling linearly with member count. Best of 5 runs of 20,000 calls, at 5/20/50/110 members: 25x/84x/316x/735x slower.

import timeit
from typing import Protocol, runtime_checkable

@runtime_checkable
class P(Protocol):
    @property
    def a(self) -> bool: ...
    @property
    def b(self) -> bool: ...

class Good:
    a = b = True

class Bad:
    a, b = True, None

for x in (Good(), Bad()):
    print(isinstance(x, P), timeit.timeit(lambda: isinstance(x, P), number=100_000))

On 3.13.13: True 0.0121 then True 0.1207. Only the timing differs.

Linked PRs
  • gh-156451

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

issue にある最小限の Protocol/runtime_checkable の再現コードから始め、メンバー数ごとに Good と Bad の処理時間を比較します。リンクされた PR gh-156451 と、そこで変更されている typing の実装を確認します。None 値のケースで線形時間の isinstance() チェックが発生しなくなり、報告されている True の結果が維持されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。