Skip to content

perf(prometheus): optimize duplicate metric splitting to O(N) complexity#1383

Merged
kongfei605 merged 1 commit into
flashcatcloud:mainfrom
kongfei605:prom_perf
Dec 25, 2025
Merged

perf(prometheus): optimize duplicate metric splitting to O(N) complexity#1383
kongfei605 merged 1 commit into
flashcatcloud:mainfrom
kongfei605:prom_perf

Conversation

@kongfei605

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings December 25, 2025 00:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the Prometheus parser's metric splitting algorithm to reduce time complexity from O(N*M) to O(N) where N is the buffer size and M is the number of metric chunks. The optimization replaces repeated bytes.Index calls with a single-pass scan using bytes.IndexByte to quickly locate potential delimiters.

  • Replaces dual bytes.Index calls per iteration with efficient bytes.IndexByte scanning
  • Adds logic to skip current delimiter when positioned at one, ensuring forward progress
  • Improves performance for large Prometheus metric payloads with many duplicate metrics

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +110 to +126
p := bytes.IndexByte(rest[scanOffset:], '#')
if p == -1 {
idx = -1
break
}

// Potential delimiter found at relative index (scanOffset + p)
candidate := rest[scanOffset+p:]

// Verify if it is indeed a header
if bytes.HasPrefix(candidate, helpHeader) || bytes.HasPrefix(candidate, typeHeader) {
idx = scanOffset + p
break
}

// False alarm (e.g. '#' inside a label or comment), continue scanning
scanOffset += p + 1

Copilot AI Dec 25, 2025

Copy link

Choose a reason for hiding this comment

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

The variable name 'p' conflicts with the Parser receiver variable in the method signature. While this is scoped within the for loop, it reduces readability and could be confusing. Consider using a more descriptive name like 'hashPos' or 'pos' instead.

Suggested change
p := bytes.IndexByte(rest[scanOffset:], '#')
if p == -1 {
idx = -1
break
}
// Potential delimiter found at relative index (scanOffset + p)
candidate := rest[scanOffset+p:]
// Verify if it is indeed a header
if bytes.HasPrefix(candidate, helpHeader) || bytes.HasPrefix(candidate, typeHeader) {
idx = scanOffset + p
break
}
// False alarm (e.g. '#' inside a label or comment), continue scanning
scanOffset += p + 1
hashPos := bytes.IndexByte(rest[scanOffset:], '#')
if hashPos == -1 {
idx = -1
break
}
// Potential delimiter found at relative index (scanOffset + hashPos)
candidate := rest[scanOffset+hashPos:]
// Verify if it is indeed a header
if bytes.HasPrefix(candidate, helpHeader) || bytes.HasPrefix(candidate, typeHeader) {
idx = scanOffset + hashPos
break
}
// False alarm (e.g. '#' inside a label or comment), continue scanning
scanOffset += hashPos + 1

Copilot uses AI. Check for mistakes.
Comment thread parser/prometheus/parser.go
@kongfei605 kongfei605 merged commit ef4e937 into flashcatcloud:main Dec 25, 2025
9 checks passed
@kongfei605 kongfei605 deleted the prom_perf branch December 25, 2025 00:43
laiwei pushed a commit to laiwei/categraf that referenced this pull request Mar 3, 2026
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.

2 participants