Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Dataclasses - Improve the performance of_dataclass_{get,set}state #103032

Open
Assignees
sobolevn
Labels
3.13bugs and security fixesperformancePerformance or resource usagestdlibPython modules in the Lib dirtopic-dataclassestype-featureA feature request or enhancement
@sobolevn

Description

@sobolevn

Feature or enhancement

I've noticed this comment yesterday:

cpython/Lib/dataclasses.py

Lines 1128 to 1131 in1fd603f

# _dataclass_getstate and _dataclass_setstate are needed for pickling frozen
# classes with slots. These could be slightly more performant if we generated
# the code instead of iterating over fields. But that can be a project for
# another day, if performance becomes an issue.

So, out of curiosity I've decided to try this out. How fast can I make it?
The results are here:

Testing ZeroFieldsDump time (before): 0.229174 secDump time (after) : 0.147407 secTesting OneFieldDump time (before): 0.260065 secDump time (after) : 0.197960 secTesting EightFieldsDump time (before): 0.331278 secDump time (after) : 0.192171 secTesting NestedFieldsDump time (before): 0.846335 secDump time (after) : 0.470739 sec

Here's the simple benchmark that I was using:

importpicklefromdataclassesimportdataclassfromtimeitimporttimeitdefperf(e):print('Testing',e.__class__.__name__)d=pickle.dumps(e)iterations=10000t1=timeit(lambda:pickle.dumps(e),number=iterations)t2=timeit(lambda:pickle.loads(d),number=iterations)print(f'Dump time:{t1:.6f} sec')print(f'Load time:{t2:.6f} sec')print()@dataclass(frozen=True,slots=True)classZeroFields:passperf(ZeroFields())@dataclass(frozen=True,slots=True)classOneField:foo:strperf(OneField('l'))@dataclass(frozen=True,slots=True)classEightFields:foo:strbar:intbaz:intspam:list[int]eggs:dict[str,str]x:booly:boolz:boolperf(EightFields("a",1,2, [1,2,3,4,5], {'a':'a','b':'b','c':'c'},True,False,True,))@dataclass(frozen=True,slots=True)classNestedFields:z1:ZeroFieldsz2:ZeroFieldse1:EightFieldse2:EightFieldse=EightFields("a",1,2, [1,2,3,4,5], {'a':'a','b':'b','c':'c'},True,False,True,)perf(NestedFields(ZeroFields(),ZeroFields(),e,e))

Here's the very rough version of what I am planning to do:

cls.__getstate__=_create_fn('__getstate__',            ['self'],            [f"return ({', '.join(f'self.{f.name}'forfinfields(cls))})"],        )

Things to do:

  1. Refactor current example code to be inline with other code generators
  2. Add__setstate__ similar support

Does it look like a good enough speed up to make this change?

CC@ericvsmith and@carljm

Metadata

Metadata

Assignees

Labels

3.13bugs and security fixesperformancePerformance or resource usagestdlibPython modules in the Lib dirtopic-dataclassestype-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp