python / python/cpython

Improve performance of dataclasses.asdict by caching field names

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

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

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

説明

Feature or enhancement

Proposal:

About 8 years ago @ericvsmith asked:

https://github.com/python/cpython/blob/c779f2324df06563b4ba3d70d0941e619ccaf5ff/Lib/dataclasses.py#L1381

By caching the field names of a dataclass on the class the performance improves:

asdict: Mean +- std dev: [main] 2.33 us +- 0.14 us -> [pr] 1.65 us +- 0.08 us: 1.41x faster
astuple: Mean +- std dev: [main] 2.77 us +- 0.15 us -> [pr] 2.15 us +- 0.09 us: 1.29x faster
f.__getstate__(): Mean +- std dev: [main] 941 ns +- 64 ns -> [pr] 360 ns +- 18 ns: 2.61x faster

Benchmark hidden because not significant (1): instance creation

Geometric mean: 1.47x faster
Test script

(executed on non-pgo build)

import pyperf

setup = """
from dataclasses import dataclass, asdict, astuple
from pickle import dumps

@dataclass
class Simple:
     i : int
     s : str
     l : list

s = Simple(10, 'hi', [3, 1, 4, 1])

@dataclass(frozen=True, slots=True)
class Frozen:
     i : int
     s : str
     l : list

f = Frozen(10, 'hi', [3, 1, 4, 1])
f.__getstate__()

"""

runner = pyperf.Runner()
runner.timeit(name="instance creation", stmt="Simple(10, 'hi', [3, 1, 4, 1])", setup=setup)
runner.timeit(name="asdict", stmt="asdict(s)", setup=setup)
runner.timeit(name="astuple", stmt="astuple(s)", setup=setup)
runner.timeit(name="f.__getstate__()", stmt="f.__getstate__()", setup=setup)

The main downside of caching the field names is that (per dataclass, not per instance) we have an additional private field on the class with a list of strings.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs
  • gh-138233

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

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

はじめの一歩

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

調査の方向性

まず、asdict と astuple の実装周辺にある Lib/dataclasses.py を確認し、その後、作業を始める前にリンクされた PR gh-138233 を調査してください。提供されている pyperf スクリプトを実行して報告されているベースラインを確立してください;完了時には dataclass の動作を維持しつつ、提案されているフィールド名のキャッシュによるパフォーマンス改善を達成する必要があります。

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

評価

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

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

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