Skip to content

msgspec.structs.fields() is 20x slower than dataclasses.fields() #963

Open

Description

@kramar11

Description

Hello, I noticed in a project where I have to frequently call msgspec.structs.fields that this method is compared to dataclasses extremely slow (about 20x slower).

from dataclasses import dataclass, fields
from timeit import timeit

import msgspec
msgspec_fields = msgspec.structs.fields


@dataclass
class D:
    x: int
    y: int | None = None
    z: str | None = None

class M(msgspec.Struct):
    x: int
    y: int | None = None
    z: str | None = None

d = D(1)
m = M(1)

print("dataclass.fields = ", end="")
print(timeit(lambda: fields(d), number=1000000))

print("msgspec.structs.fields = ", end="")
print(timeit(lambda: msgspec_fields(m), number=1000000))

Output:

dataclass.fields = 0.3529520556330681
msgspec.structs.fields = 7.523276620544493

Tested with python 3.13.7 and msgspec 0.19.0 and 0.20.0 (same result).

Maybe simply caching the data in a classvar is a fast solution here?

Activity

  1. changed the title [-]msgspec.structs.fields() is 20x slower thant dataclass.fields()[/-] [+]msgspec.structs.fields() is 20x slower than dataclasses.fields()[/+] on Dec 2, 2025
  2. provinzkraut commented on Dec 2, 2025

    @provinzkraut
    Member

    Huh, interesting. I suspect the issue is twofold:

    1. We're rebuilding this info on every invocation of fields
    2. We, very expensively, inspect the type annotations during that (https://github.com/jcrist/msgspec/blob/a9ed8f12f11269704aa25680a2273287485c9f5a/src/msgspec/structs.py#L91)

    I think it should be possible to speed this up by a lot, as we should have all the information required for this available already within the internal struct state.

  3. Siyet commented on Apr 8, 2026

    @Siyet
    Contributor

    Resolved in the community fork msgspec-arise: issue #7, released in v0.20.2.

  4. added 2 commits that reference this issue on Apr 9, 2026
    f84eac5
    3ea4c05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions