Skip to content

Avoid re-reading attributes when copying DxfProperty - #1276

Open
s1lentcs wants to merge 1 commit into
DomCR:masterfrom
s1lentcs:perf/dxf-property-copy-reflection
Open

s1lentcs wants to merge 1 commit into
DomCR:masterfrom
s1lentcs:perf/dxf-property-copy-reflection

Conversation

@s1lentcs

@s1lentcs s1lentcs commented Oct 9, 2026

Copy link
Copy Markdown

Description

Reading DXF files with many VERTEX entities spends most of its time in reflection. DxfSectionReaderBase.readVertex calls DxfClassMap.Create<T>() for every vertex; Create returns a copy of the cached map, and the DxfProperty copy constructor chains to DxfPropertyBase(PropertyInfo), which calls GetCustomAttribute<T>() again for every property. The attribute data is already available on the source property, so it is re-read needlessly once per property per vertex.

This PR adds a protected copy constructor to DxfPropertyBase<T> that reuses the source's _attributeData, _property and _assignedCode, and routes the DxfProperty copy constructor through it.

Results (large real-world DXF made up mostly of 3D polylines, Release build, runs interleaved over several rounds):

master master + this PR Change
DxfReader.Read (warm, median) 7,093 ms 4,491 ms -37%
DxfReader.Read (first read in process) 8,412 ms 5,936 ms -29%
DxfReader.ReadEntities 6,698 ms 4,365 ms -35%
Share of read time in CustomAttribute.AddCustomAttributes (profiler) 53% 0%

The entities read are identical before and after. On net9.0 and net4.8, 2,415 of 2,417 existing tests pass and 2 are skipped.

Tasks done in this PR

  • Performance: avoid re-reading DxfCodeValueAttribute via reflection when copying a DxfProperty.
  • An evil bug have been defeated.
  • Code cleanup and maintenance has been done.

Related Issues / Pull Requests

  • None.

Notes for reviewer

  • Behaviour should be unchanged:

    • _attributeData and _property are the same instances the old path would have looked up again.
    • Copying the nullable _assignedCode makes AssignedCode resolve exactly as it did on the source (explicit code, single code, or Invalid).
    • The old path's ValueCodes.Contains(code) validation is skipped. The source property already passed it when it was created.
    • StoredValue was not copied before and still isn't.
  • Two follow-ups showed up while profiling, intentionally left out of this PR to keep it focused:

    • DxfPropertyBase.SetValue resolves the property type with an IsEquivalentTo chain on every call, which is a large share of the remaining read time. Caching the type category once per property reduced it significantly.
    • DxfClassMap.Create still allocates a full map copy per vertex. The reader never mutates these maps, so it could use the cached instance directly.

    Happy to open separate PRs for either if they're of interest.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant