-
Notifications
You must be signed in to change notification settings - Fork 107
Conversation
978c8b5
to
832ccf3
Compare
{ | ||
in: Series{ | ||
Target: "a;biglongtagkeyhere=andithasabiglongtagvaluetoo;c=d", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
api/models/series_test.go
Outdated
in.Target = in.Target + randString(tagValueLength) | ||
} | ||
|
||
b.ReportAllocs() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting. everywhere else we assume if the user wants this, they use the -test.benchmem
flag.
i'm hesitant of introducing this here and creating inconsistency with other tests.
is there a clear benefit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it allows benchmarks that know that allocations are something useful to benchmark to enable them independently of other benchmarks that may run that don't need them. I can remove it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suppose it's a fair argument. but "allocations being useful to measure", doesn't that go for most benchmark code, other than perhaps very computationally expensive or io bound stuff maybe.
and i just use the alloc measures typically as a way to give color on changes in the time taken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I like allocation benchmarks on certain code, because it's less subject to noisy neighbor with local benchmarks. I removed it in my last commit though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi re noisy neighbours i use cpu isolation.
see https://gist.github.com/Dieterbe/a52c95a9603507670eb39274544ee1a8
api/models/series.go
Outdated
|
||
if s.Tags == nil { | ||
// +1 for the name tag | ||
s.Tags = make(map[string]string, numTags) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need to use numTags+1 per the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Must have gotten lost during some of my benchmark rounds
correct. https://go-review.googlesource.com/c/go/+/110055 should pay off here. |
api/models/series.go
Outdated
} | ||
|
||
index := strings.IndexByte(s.Target, ';') | ||
name := s.Target[0:index] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. surprised our qa gofmt script doesn't complain about the needless 0:
s.Tags["name"] = tagSplits[0] | ||
|
||
// Do this last to overwrite any invalid "name" tag that might be preset | ||
s.Tags["name"] = name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean with invalid? one specified by the user? maybe we should refer to those as 'illegal' or even clarify as overwrite any "name" tag that may have been illegally specified in the series tags
. or actually drop the 'illegal' because i don't think it's written anywhere that it's illegal.
api/models/series_test.go
Outdated
for i := 0; i < numTags; i++ { | ||
in.Target = in.Target + ";" + randString(tagKeyLength) | ||
in.Target = in.Target + "=" | ||
in.Target = in.Target + randString(tagValueLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not simplify this to
in.Target += ";" + randString(tagKeyLength) + "=" + randString(tagValueLength)
also, we could use https://golang.org/pkg/strings/#Builder here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shanson7 is it deliberate that you are still doing in.Target = in.Target + ...
rather then +=
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope
did you do this by uncommenting the nil setting line? instead of that, perhaps we should just have 2 separate benchmarks? to simplify reproducing the stats |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, but needs some tweaks.
Upgraded my local golang to 1.11.4 and now the map clearing approach shows it's benefit:
|
While debugging slowness in
groupByTags
, the performance of SetTags stood out. I don't believe this was the primary source of slowness in my case, but it certainly could be a contributing factor, since this is called for every series that is processed viarender
. Aside from replacingSplitN
withIndexByte
, I also only allocate a new map if the existing one isnil
. I ran the benchmark in two modes, one where I leave the Tags and one where Inil
them out.Here's the benchcmp when
s.Tags == nil
and here is when we reuse the Tags:
With a lot of tags, the cost of clearing the map is higher than reallocating, but this was go 1.10.3 and I know go 1.11 has optimized map clearing.