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

Increase escapeMetricName performance #197

Merged
merged 4 commits into from
Apr 10, 2019

Conversation

bakins
Copy link
Contributor

@bakins bakins commented Apr 2, 2019

While investigating something else,I did some profiling and found that escapeMetricName took a large amount of processing time. The regex was the majority of this time. escapeMetricName is called on every event processed.

The valid set of characters for a metric name is fairly small, so we can optimize this a bit. I replaced the regex in escapeMetricName with a loop over the runes. I originally used a strings.Builder to build the output, but building the string manually provided to be much faster.

This passes tests, but I am sure I am missing something obvious. This is borderline unreadable as well and needs some comments. I did this on a sick day, so I do not trust myself on this.

For benchmarks, see https://gist.github.com/bakins/f4d342d1cc93f4911ffd4efa9d93ecab

@bakins bakins force-pushed the escapeMetricName-performance branch from 505815f to 95fe616 Compare April 2, 2019 22:06
@SpencerMalone
Copy link
Contributor

I've been poking at this a bit, I think it's doing the right thing, and I tried playing with some alternate implementations (such as using unicode.Is() and a custom unicode.RangeTable), but nothing topped this in performance.

I think with some comments this would be great, and I personally think it's worth keeping the // Replace all illegal metric chars with underscores. (or similar) comment in place

@matthiasr
Copy link
Contributor

This looks good! I agree, a little commenting would be nice, but I don't think it's less readable than the previous solution.

Why not add the benchmark code (only for the version that is actually there)?

@bakins
Copy link
Contributor Author

bakins commented Apr 9, 2019

Added some comments and benchmark. Output on my laptop:

$ go test -bench=BenchmarkEscapeMetricName -test.benchmem
goos: darwin
goarch: amd64
pkg: github.com/prometheus/statsd_exporter
BenchmarkEscapeMetricName/clean-12         	50000000	        30.4 ns/op	      10 B/op	       2 allocs/op
BenchmarkEscapeMetricName/0starts_with_digit-12         	20000000	        80.1 ns/op	      64 B/op	       2 allocs/op
BenchmarkEscapeMetricName/with_underscore-12            	30000000	        49.4 ns/op	      32 B/op	       2 allocs/op
BenchmarkEscapeMetricName/with.dot-12                   	50000000	        35.1 ns/op	      16 B/op	       2 allocs/op
BenchmarkEscapeMetricName/with😱emoji-12                 	30000000	        50.8 ns/op	      32 B/op	       2 allocs/op
BenchmarkEscapeMetricName/with.*.multiple-12            	30000000	        51.4 ns/op	      32 B/op	       2 allocs/op
BenchmarkEscapeMetricName/test.web-server.foo.bar-12    	20000000	        65.2 ns/op	      64 B/op	       2 allocs/op
BenchmarkEscapeMetricName/#00-12                        	200000000	         7.72 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/prometheus/statsd_exporter	13.494s

@bakins bakins force-pushed the escapeMetricName-performance branch from bdb7999 to 7f70979 Compare April 9, 2019 15:58
@matthiasr
Copy link
Contributor

awesome, thank you!

@matthiasr matthiasr merged commit ece9385 into prometheus:master Apr 10, 2019
matthiasr pushed a commit that referenced this pull request Apr 10, 2019
Signed-off-by: Matthias Rampke <[email protected]>
matthiasr pushed a commit that referenced this pull request May 15, 2019
* [CHANGE] Do not run as root in the Docker container by default ([#202](#202))
* [FEATURE] Add metric for count of events by action ([#193](#193))
* [FEATURE] Add metric for count of distinct metric names ([#200](#200))
* [FEATURE] Add UNIX socket listener support ([#199](#199))
* [FEATURE] Accept Datadog [distributions](https://docs.datadoghq.com/graphing/metrics/distributions/) ([#211](#211))
* [ENHANCEMENT] Add a health check to the Docker container ([#182](#182))
* [ENHANCEMENT] Allow inconsistent label sets ([#194](#194))
* [ENHANCEMENT] Speed up sanitization of metric names ([#197](#197))
* [ENHANCEMENT] Enable pprof endpoints ([#205](#205))
* [ENHANCEMENT] DogStatsD tag parsing is faster ([#210](#210))
* [ENHANCEMENT] Cache mapped metrics ([#198](#198))
* [BUGFIX] Fix panic if a mapping resulted in an empty name ([#192](#192))
* [BUGFIX] Ensure that there are always default quantiles if using summaries ([#212](#212))
* [BUGFIX] Prevent ingesting conflicting metric types that would make scraping fail ([#213](#213))

With #192, the count of events rejected because of negative counter increments has moved into the `statsd_exporter_events_error_total` metric, instead of being lumped in with the different kinds of successful events.

Signed-off-by: Matthias Rampke <[email protected]>
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.

3 participants