[Python-checkins] gh-103000: Optimise `dataclasses.asdict` for the common case (#104364)

AlexWaygood webhook-mailer at python.org
Wed May 10 17:44:02 EDT 2023


https://github.com/python/cpython/commit/7b8d7f56b64ab4370fea77e77ea4984dd2a73979
commit: 7b8d7f56b64ab4370fea77e77ea4984dd2a73979
branch: main
author: Alex Waygood <Alex.Waygood at Gmail.com>
committer: AlexWaygood <Alex.Waygood at Gmail.com>
date: 2023-05-10T22:43:51+01:00
summary:

gh-103000: Optimise `dataclasses.asdict` for the common case (#104364)

Co-authored-by: David Ellis <ducksual at gmail.com>

files:
A Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst
M Lib/dataclasses.py

diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index b0b8a773b759..3eacba840db4 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1324,11 +1324,18 @@ def _asdict_inner(obj, dict_factory):
     if type(obj) in _ATOMIC_TYPES:
         return obj
     elif _is_dataclass_instance(obj):
-        result = []
-        for f in fields(obj):
-            value = _asdict_inner(getattr(obj, f.name), dict_factory)
-            result.append((f.name, value))
-        return dict_factory(result)
+        # fast path for the common case
+        if dict_factory is dict:
+            return {
+                f.name: _asdict_inner(getattr(obj, f.name), dict)
+                for f in fields(obj)
+            }
+        else:
+            result = []
+            for f in fields(obj):
+                value = _asdict_inner(getattr(obj, f.name), dict_factory)
+                result.append((f.name, value))
+            return dict_factory(result)
     elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
         # obj is a namedtuple.  Recurse into it, but the returned
         # object is another namedtuple of the same type.  This is
diff --git a/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst b/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst
new file mode 100644
index 000000000000..f84ec5c8b3ca
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst
@@ -0,0 +1,2 @@
+Improve performance of :func:`dataclasses.asdict` for the common case where
+*dict_factory* is ``dict``. Patch by David C Ellis.



More information about the Python-checkins mailing list