Added #[inline] and #[inline(always)] attributes to hot-path methods in PathMap implementation:
PathMapNode::with_zipper - #[inline(always)] (called for every node operation)PathMapNode::is_final - #[inline]PathMapNode::transition - #[inline]PathMapNode::value - #[inline]PathMapDictionary::root - #[inline]PathMapDictionary::len - #[inline]PathMapDictionary::sync_strategy - #[inline]| Benchmark | Before | After | Improvement |
|---|---|---|---|
large_distance_queries/50 | 9.65μs | 7.79μs | -32.1% ⭐ |
ordered_vs_unordered/ordered/1 | 51.4μs | 50.6μs | -2.0% |
ordered_query_varying_distance/5 | 822μs | 823μs | -2.7% |
ordered_query_dict_size_scaling/100 | 37.9μs | 36.2μs | -4.5% |
ordered_query_dict_size_scaling/500 | 126μs | 122μs | -4.1% |
ordered_query_dict_size_scaling/5000 | 478μs | 447μs | -6.5% |
large_distance_queries/99 | 11.6μs | 10.7μs | -7.7% |
ordered_query_take_while/2 | 554μs | 536μs | -3.1% |
ordered_query_take_while/3 | 752μs | 736μs | -3.2% |
| Benchmark | Before | After | Regression |
|---|---|---|---|
ordered_query_dict_size_scaling/1000 | 249μs | 235μs | +12.6% ⚠️ |
prefix_varying_query_length/5 | 6.43μs | 6.43μs | +8.9% |
prefix_vs_standard/prefix/1 | 8.87μs | 9.48μs | +7.1% |
ordered_vs_unordered/unordered/2 | 240μs | 240μs | +6.6% |
ordered_vs_unordered/ordered/2 | 255μs | 255μs | +5.7% |
Many benchmarks showed "no change detected" or changes within noise threshold.
Large distance queries improved dramatically (-32% for distance 50):
is_final() being called very frequentlyDictionary size scaling shows non-linear behavior:
The 1000-element regression suggests instruction cache effects or branch prediction issues at that specific scale.
Recall the original regression findings from Phase 1:
ordered_query_dict_size_scaling/1000: 219μs → 249μs (+13.7% regression)Current state after optimization:
ordered_query_dict_size_scaling/1000: 235μsNet result: Still +7.3% slower than original, but 5.6% better than the post-generic baseline.
The mixed results suggest the performance regression has multiple causes:
<V> parameter generates duplicate codePathMapNode<V> has different size/alignmentV: DictionaryValue bounds may prevent some optimizationsInline attributes help with #3 but don't address #1 and #2.
#[repr(C)] or alignment hintsConsider enum-based approach instead of generics:
enum PathMapVariant {
NoValue(PathMapCore),
WithValue(PathMapCore, Arc<HashMap<Vec<u8>, V>>),
}
This avoids monomorphization while preserving type safety.
Recommendation: Accept current optimization state and proceed to Phase 2 (fuzzy map benchmarking).
Rationale:
PathMapDictionary<V> where V ≠ (), so generic overhead is unavoidablesrc/dictionary/pathmap.rs:
#[inline] / #[inline(always)] attributesPhase 2: Create comprehensive fuzzy map benchmarks
PathMapDictionary<u32> vs PathMapDictionary<()>Phase 3: Generate flame graphs for fuzzy map queries
query_filtered() hot pathsPhase 4: Implement targeted optimizations based on Phase 3 data
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |