diff --git a/.rubocop.yml b/.rubocop.yml index f7b04c4..28ae1ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,6 +5,9 @@ inherit_gem: AllCops: TargetRubyVersion: 2.4 +Style/ParallelAssignment: + Enabled: false + Metrics/MethodLength: Max: 15 diff --git a/Gemfile.lock b/Gemfile.lock index 987c50e..cb45405 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,6 +45,7 @@ GEM unicode-display_width (>= 1.4.0, < 1.7) rubocop-rspec (1.33.0) rubocop (>= 0.60.0) + ruby-prof (0.18.0) ruby-progressbar (1.10.1) unicode-display_width (1.6.0) @@ -56,6 +57,7 @@ DEPENDENCIES prometheus-client-tracer! pry (~> 0.10) rspec (~> 3.8) + ruby-prof (~> 0.18) BUNDLED WITH 2.0.1 diff --git a/exe/benchmark-tracer.rb b/exe/benchmark-tracer.rb new file mode 100755 index 0000000..db0d92a --- /dev/null +++ b/exe/benchmark-tracer.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# This file can be used to validate the performance of the tracer is not incomparible to a +# naive tracing implementation. The performance will degrade linerarly with the number of +# on-going traces, however a modern i7 can achieve trace throughput: +# +# naive: 333k/s +# trace, 0 on-going: 233k/s +# trace, 5 on-going: 216k/s +# trace, 25 on-going: 155k/s +# trace, 100 on-going: 84k/s +# +# While this seems more than reasonable performance for almost any use case, consider +# using multiple tracers if this does become a problem. + +require "benchmark" + +require "prometheus/client" +require "prometheus/client/tracer" + +counter = Prometheus::Client::Counter.new( + :counter, docstring: "example", labels: %i[worker] +) +another_counter = Prometheus::Client::Counter.new( + :counter_another, docstring: "another example", labels: %i[] +) + +def trace(metric, labels = {}) + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield +ensure + metric.increment( + by: Process.clock_gettime(Process::CLOCK_MONOTONIC) - start, + labels: labels, + ) +end + +n_string, n_concurrent_traces_string, = ARGV +n, n_concurrent_traces = [n_string.to_i, n_concurrent_traces_string.to_i] + +n_concurrent_traces.times do + Prometheus::Client.tracer.send(:start, another_counter, {}) +end + +Benchmark.bm(7) do |x| + x.report("naive:") { n.times { trace(counter, worker: 1) { nil } } } + x.report("trace:") do + n.times { Prometheus::Client.tracer.trace(counter, worker: 1) { nil } } + end +end diff --git a/prometheus-client-tracer.gemspec b/prometheus-client-tracer.gemspec index 3da9276..25a9c9f 100644 --- a/prometheus-client-tracer.gemspec +++ b/prometheus-client-tracer.gemspec @@ -23,4 +23,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "gc_ruboconfig", "= 2.4.0" spec.add_development_dependency "pry", "~> 0.10" spec.add_development_dependency "rspec", "~> 3.8" + spec.add_development_dependency "ruby-prof", "~> 0.18" end