Giter Club home page Giter Club logo

pilfer's Introduction

Pilfer

Profile Ruby code and find out exactly how slow it runs.

Pilfer uses rblineprof to measure how long each line of code takes to execute and the number of times it was called.

Pilfer Profile.png

Take a look at some Pilfer profiles of the Bundler API site.

Installation

Using with Bundler is as simple as adding pilfer to your Gemfile.

gem 'pilfer', '~> 1.0.0'

Or install it locally like any other gem.

$ gem install pilfer

Usage

Profile a block of code saving the report to the file profile.log.

require 'pilfer'

reporter = Pilfer::Logger.new('pilfer.log')
profiler = Pilfer::Profiler.new(reporter)
profiler.profile('bubble sorting') do
  array = (0..100).to_a.shuffle
  bubble_sort array
end

Profile your Rack or Rails app using Pilfer::Middleware.

reporter = Pilfer::Logger.new('pilfer.log')
profiler = Pilfer::Profiler.new(reporter)
use Pilfer::Middleware, :profiler => profiler

The profile report consists of the wall time and call count for each line of code executed along with the total wall and CPU times for each file.

Profile start="2013-05-12 00:41:16 UTC" description="bubble sorting"
/Users/Larry/Sites/pilfer/sort.rb wall_time=42.5ms cpu_time=29.7ms
                   | require 'pilfer'
                   |
                   | def bubble_sort(container)
    42.5ms (    1) |   loop do
                   |     swapped = false
    42.3ms (   94) |     (container.size-1).times do |i|
    10.2ms ( 9400) |       if (container[i] <=> container[i+1]) == 1
     6.2ms ( 5092) |         container[i], container[i+1] = container[i+1], container[i] # Swap
                   |         swapped = true
                   |       end
                   |     end
                   |     break unless swapped
                   |   end
                   |   container
                   | end
                   |
                   | reporter = Pilfer::Logger.new($stdout)
                   | profiler = Pilfer::Profiler.new(reporter)
                   | profiler.profile_files_matching(/sort\.rb/, 'bubble sorting') do
     0.1ms (    3) |   array = (0..100).to_a.shuffle
    42.5ms (    1) |   bubble_sort array
                   | end

Step 1: Create a reporter

Decide how you want line profiles to be reported. Profiles can be sent to a pilfer-server or written to a file path or IO object.

# Send reports to a pilfer-server
reporter = Pilfer::Server.new('https://pilfer.com', 'my-pilfer-server-token')

# Append reports to a file
reporter = Pilfer::Logger.new('pilfer.log')

# Print reports to standard out
reporter = Pilfer::Logger.new($stdout)

The absolute path to each profiled file is used in the report. Set the path to the application root with :app_root to have it trimmed from reported file paths.

reporter = Pilfer::Logger.new('pilfer.log')
# Profile start=2013-05-02 14:17:26 UTC
# /Sites/bundler-api/lib/bundler-api/web.rb wall_time=1009.5ms cpu_time=0.5ms
# ...

reporter = Pilfer::Logger.new('pilfer.log', :app_root => '/Sites/bundler-api/')
# Profile start=2013-05-02 14:17:26 UTC
# lib/bundler-api/web.rb wall_time=1009.5ms cpu_time=0.5ms
# ...

Step 2: Create a profiler

A Profiler runs the line profiler and sends it to a reporter. Create one passing the reporter created in the previous step.

profiler = Pilfer::Profiler.new(reporter)

Step 3: Profile a block of code

Use Profiler#profile to profile a block of code. Optionally, provide a description of the code being profiling.

profiler.profile('bubble sorting') do
  array = (0..100).to_a.shuffle
  bubble_sort array
end

Every file that's executed by the block including code outside the application like gems and standard libraries will be included in the profile. Use #profile_files_matching to limit profiling to files whose paths match a regular expression.

# Only profile Rails models
matcher = %r{^#{Regexp.escape(Rails.root.to_s)}/app/models}
profiler.profile_files_matching(matcher, 'User.find_by_email') do
  User.find_by_email('[email protected]')
end

Additional arguments to #profile and #profile_files_matching will be passed to the reporter. The Pilfer::Server reporter, for example, can submit profiles asynchronously.

profiler.profile('bubble sorting', :submit => :async) do
  array = (0..100).to_a.shuffle
  bubble_sort array
end

Extras

Pilfer Server

Pilfer Server is your own, personal service for collecting and viewing line profiles gathered by Pilfer. Follow the Pilfer Server setup instructions to stand up a new server.

reporter = Pilfer::Server.new('https://pilfer.com', 'my-pilfer-server-token')
profiler = Pilfer::Profiler.new(reporter)
profiler.profile('bubble sorting') do
  array = (0..100).to_a.shuffle
  bubble_sort array
end

Rack Middleware

Profile your entire Rack or Rails app using Pilfer::Middleware. Pass it a Profiler created with a reporter as normal.

reporter = Pilfer::Server.new('https://pilfer.com', 'my-pilfer-server-token')
profiler = Pilfer::Profiler.new(reporter)
use Pilfer::Middleware, :profiler => profiler

Restrict profiling to files matching a regular expression using the :files_matching option. This calls Profiler#profile_files_matching using the given regular expression.

matcher = %r{^#{Regexp.escape(Rails.root.to_s)}/(app|config|lib|vendor/plugin)}
use Pilfer::Middleware, :profiler     => profiler,
                        :file_matcher => matcher

You almost certainly don't want to profile every request. Provide a block to determine if a profile should be run on the incoming request.

use Pilfer::Middleware, :profiler => profiler do
  # Profile 1% of requests.
  rand(100) == 1
end

The Rack environment is available to allow profiling on demand.

# Profile requests containing the query string ?profile=true
use Pilfer::Middleware, :profiler => profiler do |env|
  env["QUERY_STRING"].include? 'profile=true'
end

# Profile requests containing a header whose value matches a secret
use Pilfer::Middleware, :profiler => profiler do |env|
  env['HTTP_PROFILE_AUTHORIZATION'] == 'super-secret'
end

Supported Ruby Versions

This library is tested against the following Ruby versions.

  • MRI 1.9.3
  • MRI 1.8.7
  • REE

If you need a specific version supported, open and issue or send a pull request.

License

The MIT License (MIT)

Copyright (c) 2013 Eric Lindvall and Larry Marburger. See LICENSE for details.

pilfer's People

Contributors

alxgsv avatar dpsk avatar eric avatar kavu avatar lmarburger avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.