Skip to content

Reduce resource-selector benchmark regressions via selector parse caching and canonical fast-path#1884

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-benchmark-regressions
Draft

Reduce resource-selector benchmark regressions via selector parse caching and canonical fast-path#1884
Copilot wants to merge 4 commits intomainfrom
copilot/fix-benchmark-regressions

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

This PR addresses the benchmark regressions introduced around resource selector query construction and config lookup paths (ResourceSelectorConfigs/*, ResourceSelectorQueryBuild/tags) and trims repeated selector-processing overhead in hot loops.

  • Resource selector clause hot-path optimization

    • Added a cache for parsed PEG expressions used by SetResourceSelectorClause to avoid repeatedly parsing identical selector PEG strings.
    • Cached payload stores both parsed query field and flattened fields used for agent_id / deleted_at detection.
  • Selector requirements parse deduplication

    • Added a cache for parsed label/tag/field selector requirements to avoid repeated labels.Parse(...).Requirements() for the same selector strings.
    • Applied to TagSelector, LabelSelector, and FieldSelector handling in SetResourceSelectorClause.
  • Canonicalization fast-path

    • Added an early return in ResourceSelector.Canonical() when no wildcard is present, skipping normalization work on common non-wildcard selectors.
    • Added focused coverage for wildcard detection and no-wildcard canonical stability.
  • Safety hardening for cached values

    • Replaced unsafe cache type assertions with checked assertions + cache eviction on mismatch to prevent panic from malformed cache entries.
func getSelectorRequirements(selector string) ([]labels.Requirement, error) {
	if value, ok := resourceSelectorLabelRequirementsCache.Get(selector); ok {
		if cached, ok := value.(parsedSelectorRequirements); ok {
			return cached.requirements, nil
		}
		resourceSelectorLabelRequirementsCache.Delete(selector)
	}

	parsedSelector, err := labels.Parse(selector)
	if err != nil {
		return nil, err
	}
	requirements, _ := parsedSelector.Requirements()
	resourceSelectorLabelRequirementsCache.SetDefault(selector, parsedSelectorRequirements{requirements: requirements})
	return requirements, nil
}

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI changed the title [WIP] Fix benchmark regressions in resource selector configurations Reduce resource-selector benchmark regressions via selector parse caching and canonical fast-path Apr 14, 2026
Copilot AI requested a review from moshloop April 14, 2026 10:13
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 14, 2026

Benchstat (Other)

Base: 6e01f646baf3a630e0b92d7a9602a52202b1c131
Head: d37d0bd98cfe925d4ee08b5a4475c5c58d728dce

✅ 5 improvement(s)
Benchmark Base Head Change p-value
ResourceSelectorQueryBuild/name_and_type-4 63.30µ 21.41µ -66.18% 0.002
ResourceSelectorQueryBuild/name-4 43.82µ 16.42µ -62.52% 0.002
ResourceSelectorConfigs/name-4 208.3µ 174.7µ -16.13% 0.009
ResourceSelectorConfigs/name_and_type-4 227.2µ 191.6µ -15.64% 0.002
ResourceSelectorQueryBuild/tags-4 16.90µ 15.80µ -6.51% 0.004
Full benchstat output
goos: linux
goarch: amd64
pkg: github.com/flanksource/duty/bench
cpu: AMD EPYC 7763 64-Core Processor                
                                                       │ bench-base.txt │           bench-head.txt            │
                                                       │     sec/op     │    sec/op     vs base               │
InsertionForRowsWithAliases/external_users.aliases-4       591.3µ ± 19%   600.2µ ±  7%        ~ (p=0.310 n=6)
InsertionForRowsWithAliases/config_items.external_id-4     1.136m ±  9%   1.128m ± 18%        ~ (p=0.937 n=6)
ResourceSelectorConfigs/name-4                             208.3µ ±  2%   174.7µ ± 19%  -16.13% (p=0.009 n=6)
ResourceSelectorConfigs/name_and_type-4                    227.2µ ±  5%   191.6µ ± 15%  -15.64% (p=0.002 n=6)
ResourceSelectorConfigs/tags-4                             27.89m ±  6%   29.25m ±  6%        ~ (p=0.132 n=6)
ResourceSelectorQueryBuild/name-4                          43.82µ ±  4%   16.42µ ±  1%  -62.52% (p=0.002 n=6)
ResourceSelectorQueryBuild/name_and_type-4                 63.30µ ±  3%   21.41µ ±  1%  -66.18% (p=0.002 n=6)
ResourceSelectorQueryBuild/tags-4                          16.90µ ±  3%   15.80µ ±  6%   -6.51% (p=0.004 n=6)
geomean                                                    283.4µ         209.3µ        -26.13%

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 14, 2026

Benchstat (RLS)

Base: 6e01f646baf3a630e0b92d7a9602a52202b1c131
Head: d37d0bd98cfe925d4ee08b5a4475c5c58d728dce

📊 1 minor regression(s) (all within 5% threshold)

Benchmark Base Head Change p-value
RLS/Sample-15000/catalog_changes/With_RLS-4 129.8m 131.0m +0.89% 0.002
✅ 4 improvement(s)
Benchmark Base Head Change p-value
RLS/Sample-15000/change_types/With_RLS-4 5.382m 5.229m -2.84% 0.002
RLS/Sample-15000/analysis_types/With_RLS-4 3.944m 3.906m -0.95% 0.041
RLS/Sample-15000/config_types/With_RLS-4 125.5m 124.4m -0.81% 0.015
RLS/Sample-15000/configs/With_RLS-4 123.6m 122.6m -0.80% 0.002
Full benchstat output
goos: linux
goarch: amd64
pkg: github.com/flanksource/duty/bench
cpu: AMD EPYC 7763 64-Core Processor                
                                               │ bench-base.txt │          bench-head.txt           │
                                               │     sec/op     │   sec/op     vs base              │
RLS/Sample-15000/catalog_changes/Without_RLS-4      5.311m ± 1%   5.316m ± 3%       ~ (p=0.589 n=6)
RLS/Sample-15000/catalog_changes/With_RLS-4         129.8m ± 1%   131.0m ± 1%  +0.89% (p=0.002 n=6)
RLS/Sample-15000/config_changes/Without_RLS-4       5.329m ± 1%   5.273m ± 2%       ~ (p=0.093 n=6)
RLS/Sample-15000/config_changes/With_RLS-4          128.3m ± 1%   127.7m ± 1%       ~ (p=0.310 n=6)
RLS/Sample-15000/config_detail/Without_RLS-4        3.966m ± 2%   4.002m ± 1%       ~ (p=0.180 n=6)
RLS/Sample-15000/config_detail/With_RLS-4           124.1m ± 0%   124.3m ± 1%       ~ (p=0.240 n=6)
RLS/Sample-15000/config_names/Without_RLS-4         12.61m ± 1%   12.67m ± 1%       ~ (p=0.485 n=6)
RLS/Sample-15000/config_names/With_RLS-4            124.6m ± 2%   125.1m ± 5%       ~ (p=0.394 n=6)
RLS/Sample-15000/config_summary/Without_RLS-4       60.23m ± 3%   59.77m ± 1%       ~ (p=0.132 n=6)
RLS/Sample-15000/config_summary/With_RLS-4          741.4m ± 1%   738.6m ± 1%       ~ (p=0.240 n=6)
RLS/Sample-15000/configs/Without_RLS-4              7.110m ± 4%   7.080m ± 1%       ~ (p=0.132 n=6)
RLS/Sample-15000/configs/With_RLS-4                 123.6m ± 2%   122.6m ± 0%  -0.80% (p=0.002 n=6)
RLS/Sample-15000/analysis_types/Without_RLS-4       3.910m ± 2%   3.912m ± 1%       ~ (p=0.937 n=6)
RLS/Sample-15000/analysis_types/With_RLS-4          3.944m ± 3%   3.906m ± 2%  -0.95% (p=0.041 n=6)
RLS/Sample-15000/analyzer_types/Without_RLS-4       3.736m ± 1%   3.748m ± 1%       ~ (p=0.180 n=6)
RLS/Sample-15000/analyzer_types/With_RLS-4          3.770m ± 3%   3.793m ± 2%       ~ (p=0.394 n=6)
RLS/Sample-15000/change_types/Without_RLS-4         5.262m ± 1%   5.298m ± 2%       ~ (p=0.310 n=6)
RLS/Sample-15000/change_types/With_RLS-4            5.382m ± 0%   5.229m ± 2%  -2.84% (p=0.002 n=6)
RLS/Sample-15000/config_classes/Without_RLS-4       3.302m ± 1%   3.309m ± 1%       ~ (p=0.310 n=6)
RLS/Sample-15000/config_classes/With_RLS-4          123.2m ± 1%   124.2m ± 0%       ~ (p=0.065 n=6)
RLS/Sample-15000/config_types/Without_RLS-4         3.981m ± 0%   3.947m ± 2%       ~ (p=0.240 n=6)
RLS/Sample-15000/config_types/With_RLS-4            125.5m ± 1%   124.4m ± 0%  -0.81% (p=0.015 n=6)
geomean                                             19.24m        19.21m       -0.17%

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.

Fix benchmark regressions in https://github.com/flanksource/duty/pull/1881

3 participants