Skip to content

Commit

Permalink
Basic support for profiling with bin/rubocop-profile
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre committed Jul 7, 2020
1 parent ad4e89a commit 7e0d0a3
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Expand Up @@ -65,3 +65,7 @@ TAGS

# For bundle binstubs
bin/*
!bin/rubocop-profile

# For stackprof or others
tmp/*
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### New features

* [#8242](https://github.com/rubocop-hq/rubocop/pull/8242): Internal profiling available with `bin/rubocop-profile` and rake tasks. ([@marcandre][])

## 0.87.1 (2020-07-07)

### Bug fixes
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -14,6 +14,7 @@ gem 'rubocop-rspec', '~> 1.39.0'
# Stop upgrading SimpleCov until the following issue will be resolved.
# https://github.com/codeclimate/test-reporter/issues/418
gem 'simplecov', '~> 0.10', '< 0.18'
gem 'stackprof', platform: :mri
gem 'test-queue'
gem 'yard', '~> 0.9'

Expand Down
16 changes: 16 additions & 0 deletions bin/rubocop-profile
@@ -0,0 +1,16 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'stackprof'

StackProf.start
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
begin
load "#{__dir__}/../exe/rubocop"
ensure
delta = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
StackProf.stop
Dir.mkdir('tmp') unless File.exist?('tmp')
StackProf.results('tmp/stackprof.dump')
puts "Finished in #{delta.round(1)} seconds"
end
40 changes: 40 additions & 0 deletions tasks/prof.rake
@@ -0,0 +1,40 @@
# frozen_string_literal: true

namespace :prof do
DUMP_PATH = 'tmp/stackprof.dump'

desc 'Run RuboCop on itself with profiling on'
task :run, [:path] do |_task, args|
path = args.fetch(:path, '.')
cmd = "bin/rubocop-profile #{path}"
system cmd
end

task :run_if_needed, [:path] do
Rake::Task[:run].run unless File.exist?(DUMP_PATH)
end

desc 'List the slowest cops'
task slow_cops: :run_if_needed do
method = 'RuboCop::Cop::Commissioner#trigger_responding_cops'
cmd = "stackprof #{DUMP_PATH} --text --method '#{method}'"
puts cmd
output = `#{cmd}`
_header, list, _code = *output
.lines
.grep_v(/RuboCop::Cop::Commissioner/) # ignore internal calls
.slice_when { |line| line.match?(/callees.*:|code:/) }
puts list.first(40)
end

desc 'Check a particular method by walking through the callstack'
task :walk, [:method] => :run_if_needed do |_task, args|
method = args.fetch(:method) do
warn 'usage: bundle exec rake walk[Class#method]'
exit!
end
cmd = "stackprof #{DUMP_PATH} --walk --method '#{method}'"
puts cmd
system cmd
end
end

0 comments on commit 7e0d0a3

Please sign in to comment.