Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microoptimise matching #2005

Merged
merged 4 commits into from
Oct 5, 2016
Merged

Conversation

redbaron
Copy link
Contributor

@redbaron redbaron commented Sep 18, 2016

Series of patches with minor matching optimizations.

ab65905 - adds BenchmarkQueryRange to measure effect of future changes
e222d40 - avoids extra iteration over possible results, run matchers checks before adding to a result instead
1121364 - extracts logic which prepares candidate FPs into a separate method
9b15a3b - adds fpsForLabelMatchers and seriesForLabelMatchers methods and uses them where appropriate

Before (as of ab65905):

go test -bench BenchmarkQueryRange -run none -benchtime=10s -benchmem
    1000      14723524 ns/op     5013534 B/op      83059 allocs/op

After:

go test -bench BenchmarkQueryRange -run none -benchtime=10s -benchmem
    1000      11553489 ns/op     4688423 B/op      82596 allocs/op

@redbaron redbaron force-pushed the microoptimise-matching branch from 580cc3a to 7d660ce Compare September 19, 2016 16:23
@redbaron
Copy link
Contributor Author

rebased

@redbaron
Copy link
Contributor Author

Can someone have a look please? It is up to 30% speedup on QueryRange benchmark

@beorn7
Copy link
Member

beorn7 commented Sep 20, 2016

It's on my review queue, I'm just totally overloaded, as usual...

@redbaron redbaron force-pushed the microoptimise-matching branch from 7d660ce to 9b15a3b Compare September 20, 2016 10:23
Copy link
Member

@beorn7 beorn7 left a comment

Choose a reason for hiding this comment

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

Thanks for doing this.

I have mostly just style nits.

@@ -417,11 +417,11 @@ func (s *MemorySeriesStorage) WaitForIndexing() {
func (s *MemorySeriesStorage) LastSampleForLabelMatchers(_ context.Context, cutoff model.Time, matcherSets ...metric.LabelMatchers) (model.Vector, error) {
fps := map[model.Fingerprint]struct{}{}
for _, matchers := range matcherSets {
fpToMetric, err := s.metricsForLabelMatchers(cutoff, model.Latest, matchers...)
fps1, err := s.fpsForLabelMatchers(cutoff, model.Latest, matchers...)
Copy link
Member

Choose a reason for hiding this comment

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

Please use a more descriptive name than fps1. For example, you could call this fps, and the original fps above mergedFPs or something.

for fp := range fpToMetric {
it := s.preloadChunksForRange(fp, from, through)
iterators := make([]SeriesIterator, 0, len(fpSeriesPairs))
for _, v := range fpSeriesPairs {
Copy link
Member

Choose a reason for hiding this comment

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

How about pair or p instead of v?

for fp := range fpToMetric {
it := s.preloadChunksForInstant(fp, from, through)
iterators := make([]SeriesIterator, 0, len(fpSeriesPairs))
for _, v := range fpSeriesPairs {
Copy link
Member

Choose a reason for hiding this comment

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

As above.

@@ -563,55 +563,55 @@ func (s *MemorySeriesStorage) MetricsForLabelMatchers(
return metrics, nil
}

func (s *MemorySeriesStorage) metricsForLabelMatchers(
from, through model.Time,
// returns candidate FPs for given matchers and remaining matchers to be checked
Copy link
Member

Choose a reason for hiding this comment

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

Start with "candidateFPsForLabelMatchers" and end with a period.

return nil, err
}

FP_LOOP:
Copy link
Member

Choose a reason for hiding this comment

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

As above.

Copy link
Member

Choose a reason for hiding this comment

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

With my comment above, this comment finally makes sense. Use FPLoop:

if series == nil {
return nopIter
}

s.fpLocker.Lock(fp)
Copy link
Member

Choose a reason for hiding this comment

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

As discussed in the other PR, the performance gain of not going with defer is probably negligible in this context, and will go away with Go1.8 anyway. Better use the cleaner code here (i.e. unlock with defer as before).

if series == nil {
return nopIter
}

s.fpLocker.Lock(fp)
Copy link
Member

Choose a reason for hiding this comment

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

Same as above, unlock with defer.

@@ -888,40 +963,42 @@ func (s *MemorySeriesStorage) seriesForRange(
}

func (s *MemorySeriesStorage) preloadChunksForRange(
fp model.Fingerprint,
fpsPair fingerprintSeriesPair,
Copy link
Member

Choose a reason for hiding this comment

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

fpsPair is misleading. (Pair of two FPs?). I'd just call it pair.

return iter
}

func (s *MemorySeriesStorage) preloadChunksForInstant(
fp model.Fingerprint,
fpsPair fingerprintSeriesPair,
Copy link
Member

Choose a reason for hiding this comment

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

See above.

@@ -65,3 +65,7 @@ func NewTestStorage(t testutil.T, encoding chunkEncoding) (*MemorySeriesStorage,

return storage, closer
}

func mkFpSeriesPair(s *MemorySeriesStorage, fp model.Fingerprint) fingerprintSeriesPair {
Copy link
Member

@beorn7 beorn7 Sep 22, 2016

Choose a reason for hiding this comment

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

Capitalization nit: mkFPSeriesPair. But given the name of the returned type (where FP is not abbreviated), and given that "make" is rarle abrreviated "mk" in typical Go constructors, why not call it makeFingerprintSeriesPair after all?

@beorn7
Copy link
Member

beorn7 commented Sep 28, 2016

@redbaron Ping?

@redbaron
Copy link
Contributor Author

@beorn7 will be able to do sometime this week

Should be marginally faster and somewhat more GC friendly
…chers method

No functional changes otherwise
@redbaron redbaron force-pushed the microoptimise-matching branch 2 times, most recently from 4f50e9b to 0a16958 Compare October 2, 2016 16:43
@redbaron
Copy link
Contributor Author

redbaron commented Oct 2, 2016

@beorn7 , made suggested changes

@redbaron
Copy link
Contributor Author

redbaron commented Oct 4, 2016

sorry, I didn't know this PR is holding a release back. I'll keep this tab open and expect to be able to make fixes if needed within an hour.

}

result := []fingerprintSeriesPair{}
FP_LOOP:
Copy link
Member

Choose a reason for hiding this comment

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

My comment here got lost: Don't use snake case in Go. Use something like FPLoop:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@beorn7
Copy link
Member

beorn7 commented Oct 5, 2016

Thanks. The only missing nit is the one about the loop labels. See comments above. After that, we can merge.

@redbaron redbaron force-pushed the microoptimise-matching branch from 0a16958 to fc50365 Compare October 5, 2016 13:51
@beorn7
Copy link
Member

beorn7 commented Oct 5, 2016

Sorry for the nit, but ALLCAPS is also not very Go idiomatic. Please use FPLoop as label name.

These more specific methods have replaced `metricForLabelMatchers`
in cases where its  `map[fingerprint]metric` result type was
not necessary or was used as an intermediate step

Avoids duplicated calls to `seriesForRange` from
`QueryRange` and `QueryInstant` methods.
@redbaron redbaron force-pushed the microoptimise-matching branch from fc50365 to e6db9f8 Compare October 5, 2016 14:16
@redbaron
Copy link
Contributor Author

redbaron commented Oct 5, 2016

fixed, I wasn't reading careful enough :)

@beorn7
Copy link
Member

beorn7 commented Oct 5, 2016

Thank you. Merging now.

@beorn7 beorn7 merged commit 1e2f03f into prometheus:master Oct 5, 2016
@redbaron redbaron deleted the microoptimise-matching branch October 5, 2016 15:28
@redbaron
Copy link
Contributor Author

Do you still keep authors.md up to date?

@beorn7
Copy link
Member

beorn7 commented Oct 31, 2016

In principle, yes. It definitely needs a major update. I had a script for it somewhere…

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