Repository navigation
perf(read): build full class names by string concatenation - #920
Merged
Merged
Conversation
matnwb.common.composeFullClassName runs once for every typed object read from a file, through io.getNeurodataTypeInfo. Building the name with compose took about 1.8 ms per call, almost all of the function's time. Concatenating the strings takes about 0.004 ms and gives the same result for scalar, vector and empty inputs. Reading a file with 500 sweeps takes 8.5 s instead of 9.7 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #920 +/- ##
==========================================
+ Coverage 95.29% 95.30% +0.01%
==========================================
Files 239 239
Lines 8795 8795
==========================================
+ Hits 8381 8382 +1
+ Misses 414 413 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ehennestad
enabled auto-merge
October 2, 2026 08:01
bendichter
approved these changes
Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Speeds up
nwbReadby building the class name of each typed object with string concatenation instead ofcompose: a 500-sweep file reads in 9.69 s instead of 11.92 s.Problem —
nwbReadbuilds the MATLAB class name of every typed group and dataset it reads, for exampletypes.core.CurrentClampSeriesfrom the namespacecoreand the typeCurrentClampSeries. Building each name took about 1.9 ms, almost all of it in thecomposecall that joins the parts. A patch-clamp file with 500 sweeps has about 2,000 typed objects, so building class names alone adds several seconds to the read. On the DANDI:000541 file from #567, it was about 13% of the read time.Solution — The parts are joined by string concatenation, which takes about 0.004 ms and gives the same names. Reading the 500-sweep file takes 9.69 s instead of 11.92 s.
Related: #567, #914, #915 and #919, which remove other per-object costs when reading.
What changed
nwbReadspends almost no time building class names. Reading a file with many typed objects is about 12–19% faster, depending on the file.Implementation notes
matnwb.common.composeFullClassNamenow returns"types." + namespaceName + "." + neurodataTypeinstead ofcompose("types.%s.%s", namespaceName, neurodataType). The two give identical results for scalar, column, mixed scalar and column, and empty inputs. The function had no tests;ComposeFullClassNameTestcovers these cases and the existing name corrections.Examples
Reading a patch-clamp file with 500 sweeps
The file has one
CurrentClampSeriesper sweep; the code that creates it is in #914. This reads the file and reports the fastest of three reads. The file and the code are the same before and after.Before — All 500 sweeps are read in almost 12 seconds.
After — The same sweeps are read in about 2 seconds less.
How to test
Run the example above on
mainand on this branch. The class names are covered by:runtests("tests.unit.common.ComposeFullClassNameTest")Checklist
fix #XXwhereXXis the issue number?🤖 Generated with Claude Code