An open API service indexing awesome lists of open source software.

https://github.com/splattael/hotch

Profile helper
https://github.com/splattael/hotch

memory-profiler profiler ruby

Last synced: 10 months ago
JSON representation

Profile helper

Awesome Lists containing this project

README

          

# Hotch

[![Gem Version](https://img.shields.io/gem/v/hotch.svg)](https://rubygems.org/gems/hotch)
[![Source code](https://img.shields.io/badge/code-GitHub-blue.svg)](https://github.com/splattael/hotch)

Profile helper

## What?

### Callstack profiler

* Wraps your program run with [stackprof](https://rubygems.org/gems/stackprof)
* Dumps profile results
* Converts a profile dump using [graphviz](http://www.graphviz.org/) (dot) to SVG
* Optionally shows the call-stack graph after program exit

### Memory profiler

* Traces memory allocation using [allocation_tracer](https://rubygems.org/gems/allocation_tracer)
* Prints the results formatted and sorted by object count

## Example

### Callstack profiler

From [dry-validation](https://github.com/dry-rb/dry-validation) [benchmarks/profile_schema_call_valid.rb](https://github.com/dry-rb/dry-validation/blob/3d090eeafac9d1c31fdc3e054f8fd5ec900e12f9/benchmarks/profile_schema_call_valid.rb):

![dry-validation](images/dry-validation.profile_schema_call_valid.png?raw=true "benchmarks/profile_schema_call_valid.rb")

### Memory profiler

```
filename type count old_count total_age min_age max_age total_memsize
inline.rb:28 T_IMEMO 1 0 0 0 0 0
dry/struct/class_interface.rb:74 T_IMEMO 1 0 0 0 0 0
dry/struct/class_interface.rb:77 T_IMEMO 1 0 0 0 0 0
dry/types/decorator.rb:28 T_IMEMO 1 0 0 0 0 0
dry/types/hash/schema.rb:96 T_IMEMO 2 0 0 0 0 0
dry/types/hash/schema.rb:52 T_IMEMO 2 0 0 0 0 0
inline.rb:27 T_STRING 1000 0 0 0 0 0
inline.rb:28 T_HASH 1000 0 0 0 0 0
inline.rb:26 T_HASH 1000 0 0 0 0 0
dry/types/hash/schema.rb:92 T_HASH 2000 0 0 0 0 0
dry/types/hash/schema.rb:60 T_HASH 2000 0 0 0 0 0
dry/logic/rule.rb:0 T_ARRAY 2000 0 0 0 0 0
dry/logic/rule.rb:47 T_OBJECT 2000 0 0 0 0 0
dry/types/definition.rb:59 T_OBJECT 2000 0 0 0 0 0
dry/struct/class_interface.rb:77 T_OBJECT 2000 0 0 0 0 0
dry/types/constrained.rb:20 T_DATA 4000 0 0 0 0 0
dry/types/constrained.rb:27 T_ARRAY 4000 0 0 0 0 0
dry/logic/rule.rb:47 T_ARRAY 4000 0 0 0 0 0
dry/logic/rule.rb:47 T_DATA 4000 0 0 0 0 0
dry/types/definition.rb:51 T_ARRAY 4000 0 0 0 0 0
dry/types/hash/schema.rb:92 T_ARRAY 6000 0 0 0 0 0
dry/struct.rb:16 T_STRING 6000 0 0 0 0 0
TOTAL 47008 0 0 0 0 0
```

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'hotch', '~> 0.7.0'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install hotch

## Usage

### Profile complete program

$ ruby -rhotch/run my_program.rb
Profile SVG: /tmp/hotch.my_program20150104-17330-18t4171/profile.svg
$ view /tmp/hotch.my_program20150104-17330-18t4171/profile.svg

### Profile blocks in your program

```ruby
require 'hotch'

def expensive_method
# ...
end

Hotch() do
1000.times do
expensive_method
end
end

Hotch(aggregate: false) do
1000.times do
# this run is not aggregated
end
end

Hotch() do
1000.times do
# aggregated again
end
end
```

### Auto-view

Set envvar `HOTCH_VIEWER` to enable auto-view after profiling.

$ export HOTCH_VIEWER=eog # use Gnome viewer

### Filter

Set envvar `HOTCH_FILTER` to (regexp) filter frames by its name.

$ export HOTCH_FILTER=ROM
$ export HOTCH_FILTER=Bundler

### Minitest integration

Load `hotch/minitest` in your `test/test_helper.rb` like this:

```ruby
require 'minitest/autorun'
require 'hotch/minitest'

Hotch::Minitest.run
Hotch::Minitest.run(filter: /MyClass/)
Hotch::Minitest.run(options: )
Hotch::Minitest.run(options: { limit: 200 })
```

### Memory profiler

Shell usage:

$ ruby -rhotch/memory/run my_program.rb

Require `hotch/memory` and use `Hotch.memory { ... }` as in:

```ruby
require "bundler/setup"

require "dry-types"
require "dry-struct"
require "hotch/memory"

module Types
class IntStruct < Dry::Struct
include Dry::Types.module
constructor_type :strict
attribute :int, Strict::Int
end

class Success < Dry::Struct
include Dry::Types.module
constructor_type :strict
attribute :string, Strict::String
attribute :sub, Types::IntStruct
end
end

# For more stable results the GC is disabled by default during runs.
Hotch.memory do
1000.times do
Types::Success.new(
:string => "string",
:sub => Types::IntStruct.new(:int => 1)
)
end
end

# In order to prevent disabling the GC during runs do:
Hotch.memory(disable_gc: false) do
# ...
end

# Disable aggregation between runs:
Hotch.memory(aggregate: false) do
# this run is not aggregated
end
```

#### Inline reporting

This prints two ASCII tables showing the object alloctions two calls:

```ruby
puts Hotch::Memory.report("memory") {
# ...
}

puts Hotch::Memory.report("another") {
# ...
}
```

### Minitest integration for the memory profiler

Load `hotch/memory/minitest` in your `test/test_helper.rb` like this:

```ruby
require 'minitest/autorun'
require 'hotch/memory/minitest'

Hotch::Memory::Minitest.run
Hotch::Memory::Minitest.run(name: "my name")
Hotch::Memory::Minitest.run(disable_gc: false) # on by default
```

## Caveat

### Using with bundler

If you use `hotch` in project managed by `bundler` you have to specify `hotch` in `Gemfile`.(see Installation section above)

## Contributing

1. Fork it ( https://github.com/splattael/hotch/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request

## Release

Follow these steps to release this gem:

# Increase version
edit lib/hotch/version.rb
edit README.md
# Commit
git commit -am "Release vX.Y.Z"
rake release