0.0
The project is in a healthy, maintained state
Quickly benchmark execution time and profile memory allocations for specific or all instance methods within a class. Include ClassProfiler to get `benchmark_methods` and `profile_methods` helpers and collect results via `benchmarked` and `profiled_memory`.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme

ClassProfiler: track performance and memory allocations in Ruby classes

Installation

Add this line to your application's Gemfile:

gem 'class-profiler'

And then execute:

bundle install

Or install it yourself as:

gem install class-profiler

Usage

Include ClassProfiler in your class. Use the unified class-level helpers to wrap methods.

class Report
  include ClassProfiler

  def fetch
    sleep 0.01
    'ok'
  end

  def allocate
    Array.new(1000) { 'x' * 10 }
  end

  # Track non-inherited public/protected/private instance methods (default)
  track_performance
  track_memory
end

r = Report.new
r.fetch
r.allocate

# Per-method metrics
r.performance        # => { fetch: { time: 0.0102, total: 0.0306 } }
r.memory             # => { allocate: { allocated_objects: 1005, malloc_increase_bytes: 8192 } }

# Combined view (performance + memory)
r.profile            # => { fetch: { time: 0.0102 }, allocate: { objects: 1005, bytes: 8192 } }

# Reports
r.performance_report # prints a table of last time and total time
r.memory_report      # prints a table of allocations/bytes
r.profile_report     # prints a combined table

Selection is controlled via flags on the unified helpers:

# Include inherited methods?
track_performance inherited: true
track_memory inherited: true

# Choose visibilities (public/protected/private default to true)
track_performance protected: false, private: false
track_memory public: true, protected: false, private: false

API

  • track_performance(inherited: false, public: true, protected: true, private: true)
  • track_memory(inherited: false, public: true, protected: true, private: true)
  • performance (instance): Hash of method name → { time: Float, total: Float }
  • memory (instance): Hash of method name → allocation deltas
    • allocated_objects (Integer)
    • malloc_increase_bytes (Integer)
  • profile (instance): Combined Hash of method name → { time:, objects:, bytes: }
  • performance_report, memory_report, profile_report (instance): print tabular reports

Composing with wrap_method

You can compose custom behaviors using the built-in wrap_method helper from ClassProfiler::Methods. This is the same mechanism used by the Performance and Memory modules under the hood.

class Widget
  include ClassProfiler

  def compute(x, y)
    x + y
  end

  # Add custom logging around the original implementation
  wrap_method :compute do |original, *args|
    profiler_logger.info("compute called with #{args.inspect}")
    result = original.bind(self).call(*args)
    profiler_logger.info("compute returned #{result}")
    result
  end

  # You can still benchmark or profile the same method
  track_performance
  # track_memory
end

w = Widget.new
w.compute(2, 3)
w.performance[:compute] # => { time:, total: }

Requirements

  • Ruby >= 3.1

Development

  • Run bin/setup to install dependencies
  • Run rake to execute tests and RuboCop
  • Run bin/console to experiment in Pry

Examples (speed vs memory trade-offs)

Explore the gem with runnable examples that contrast time vs memory usage for common problems.

Run all examples:

bundle exec rake examples

What you'll see:

=== Two Sum: brute_force (low memory, slower) vs hashmap (higher memory, faster) ===
Input SIZE=5000

Summary (lower time is better; lower allocations usually better):
Method           Time (s)     Allocated Objects     Malloc +bytes
----------------------------------------------------------------------
brute_force      0.456789     12345                 0
hashmap          0.012345     45678                 8192

Speed: hashmap is 37.00x faster than brute_force
Memory: hashmap allocates 3.70x more objects than brute_force

Raw reports:
...

You can run individual examples and tune sizes:

# Two Sum: brute force vs hash map
SIZE=10000 bundle exec ruby examples/two_sum.rb

# Primes: trial division vs sieve of Eratosthenes
N=50000 bundle exec ruby examples/primes.rb

Each example prints a concise table plus a human-readable conclusion highlighting the trade-off (e.g. "sieve is 10x faster but allocates 4x more objects").

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/omgreenfield/class-profiler.

License

The gem is available as open source under the terms of the MIT License.