Skip to content

perf: speed up Parquet reading via LRU shard cache#5619

Draft
benjaminhuth wants to merge 8 commits into
acts-project:mainfrom
benjaminhuth:speed-up-parquet-reading
Draft

perf: speed up Parquet reading via LRU shard cache#5619
benjaminhuth wants to merge 8 commits into
acts-project:mainfrom
benjaminhuth:speed-up-parquet-reading

Conversation

@benjaminhuth

Copy link
Copy Markdown
Member

Replace the per-event Arrow dataset scan with an LRU shard cache. The old path decompressed the full shard row group (~750 MB for ColliderML) on every readEvent() call. The new path decompresses each shard once on first access and serves subsequent events with an in-memory Table::Slice, reducing per-event I/O cost by ~100x for sequential processing.

Replace the per-event Arrow dataset scan with an LRU shard cache.
The old path decompressed the full shard row group (~750 MB) on every
readEvent() call. The new path decompresses each shard once on first
access and serves subsequent events with an in-memory Table::Slice,
reducing per-event I/O cost by ~100x for sequential processing.

Key changes:
- Add Acts::LRUCache<Key,Value> template utility with O(1) get/put/evict
- ParquetDatasetReader builds an event→shard index at construction (binary
  search replaces multi-file dataset filter pushdown in the hot path)
- On cache miss, loadShard() uses the Dataset API on the single shard file
  so missing columns are still materialized as nulls (schema evolution)
- ParquetReader::Config gains shardCacheCapacity (default 1; set to
  numThreads for parallel runs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the next milestone Jun 29, 2026
@github-actions github-actions Bot added Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Plugins Affects one or more Plugins labels Jun 29, 2026
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

📊: Physics performance monitoring for b43d598

Full contents

physmon summary

❗️: Downstream build failure

  • eic-shell EICrecon (cc @acts-project/epic-contacts)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantic comment of the day: LruCache!

benjaminhuth and others added 3 commits June 30, 2026 11:09
Add `keepParticlesWithoutHits` (default false) to
`ColliderMLRelease1InputConverter::Config`. When false, pre-scan the
hits table's `particle_id` column into an unordered_set before the
particle loop so only particles referenced by at least one hit are
constructed and inserted into the output container.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The loadShard() function uses the Arrow Dataset scanner, which requires
compute functions (e.g. make_struct) to be registered. This was broken
when ensureComputeInitialized() was removed during the LRU cache
refactor. Restore it as a std::call_once guard inside loadShard().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
asVector() returned std::vector<uint32_t>, causing a heap allocation on
every Barcode comparison. Since the size is always exactly 5, switch to
std::array<uint32_t, 5> and remove the old accessor. Update all call
sites (CsvParticleWriter, CsvSimHitWriter, BarcodeTests) accordingly.

This eliminates malloc/free overhead in every sorted Barcode container
operation (flat_multimap sort in invertIndexMultimap, TrackTruthMatcher
map lookups, ParticleSelector binary search), yielding ~1.8× overall
speedup on a 100-event ColliderML PU200 benchmark.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added Component - Fatras Affects the Fatras module Event Data Model labels Jun 30, 2026
benjaminhuth and others added 4 commits June 30, 2026 13:41
The particleTruthHitCount map is built by iterating all hits in the
measurement-particles map, incrementing a counter per SimBarcode key.
Using std::map gave O(N log N) insertions with Barcode comparisons;
switching to std::unordered_map (SimBarcode already has std::hash)
makes the accumulation loop O(N) and lookups O(1).

Yields ~3× speedup on TrackTruthMatcher (~10% overall on a 100-event
ColliderML PU200 benchmark).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
runColliderMLTruthTracking() now takes particlesDir/hitsDir instead of
inputDir and only returns the Sequencer (no perf writers), following the
parquet-reading perf refactor. Update the test to match and drop the
ROOT output assertions for writers that are no longer added.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

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

Labels

Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Fatras Affects the Fatras module Component - Plugins Affects one or more Plugins Event Data Model

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants