<commit_before>require 'benchmark'

module Stickshift
  class << self; attr_accessor :top_level_trigger; end
  class Timer
    def self.current;         Thread.current['__stickshift']; end
    def self.current=(timer); Thread.current['__stickshift'] = timer; end
    attr_reader :depth

    def initialize(obj, meth, options, *args)
      @depth, @options, @args = 1, options, args
      @label = if @options[:label]
        @options[:label]
      else
        klass = Class === obj ? "#{obj.name}." : "#{obj.class.name}#"
        "#{klass}#{meth}"
      end
      @label << "{#{obj.inspect}}"                         if @options[:inspect_self]
      @label << "(#{@args[@options[:with_args]].inspect})" if @options[:with_args]
      if @parent = Timer.current
        @parent.add(self)
        @depth = @parent.depth + 1
      end
    end

    def enabled?
       Timer.current || Stickshift.top_level_trigger.nil? || @options[:top_level]
    end

    def invoke(&block)
      return block.call unless enabled?
      begin
        Timer.current = self
        result = nil
        @elapsed = Benchmark.realtime do
          result = block.call
        end
        result
      ensure
        Timer.current = @parent
        report unless @parent
      end
    end

    def add(child)
      children << child
    end

    def children
      @children ||= []
    end

    def elapsed
      @elapsed ||= 0
    end

    def report
      $stdout.puts "#{self_format % self_time}ms >#{'  ' * @depth}#{@label} < #{total_time}ms"
      children.each {|c| c.report}
    end

    def ms(t)
      (t * 1000).to_i
    end

    def self_format
      @self_format ||= @parent.self_format if @parent
      @self_format ||= "%#{total_time.to_s.length}s"
    end

    def self_time
      @self_time ||= ms(elapsed - children.inject(0) {|sum,el| sum += el.elapsed}).to_s
    end

    def total_time
      ms(elapsed)
    end
  end
end

class Module
  def instrument(*meths)
    options = Hash === meths.last ? meths.pop : {}<commit_msg>Add Stickshift.enabled and Stickshift.output<commit_after>require 'benchmark'

module Stickshift
  class << self; attr_accessor :enabled, :top_level_trigger, :output; end
  @enabled = true
  @output = $stdout

  class Timer
    def self.current;         Thread.current['__stickshift']; end
    def self.current=(timer); Thread.current['__stickshift'] = timer; end
    attr_reader :depth

    def initialize(obj, meth, options, *args)
      @depth, @options, @args = 1, options, args
      @label = if @options[:label]
        @options[:label]
      else
        klass = Class === obj ? "#{obj.name}." : "#{obj.class.name}#"
        "#{klass}#{meth}"
      end
      @label << "{#{obj.inspect}}"                         if @options[:inspect_self]
      @label << "(#{@args[@options[:with_args]].inspect})" if @options[:with_args]
      if @parent = Timer.current
        @parent.add(self)
        @depth = @parent.depth + 1
      end
    end

    def enabled?
     Stickshift.enabled && (Timer.current || Stickshift.top_level_trigger.nil? || @options[:top_level])
    end

    def invoke(&block)
      return block.call unless enabled?
      begin
        Timer.current = self
        result = nil
        @elapsed = Benchmark.realtime do
          result = block.call
        end
        result
      ensure
        Timer.current = @parent
        report unless @parent
      end
    end

    def add(child)
      children << child
    end

    def children
      @children ||= []
    end

    def elapsed
      @elapsed ||= 0
    end

    def report
      Stickshift.output.puts "#{self_format % self_time}ms >#{'  ' * @depth}#{@label} < #{total_time}ms"
      children.each {|c| c.report}
    end

    def ms(t)
      (t * 1000).to_i
    end

    def self_format
      @self_format ||= @parent.self_format if @parent
      @self_format ||= "%#{total_time.to_s.length}s"
    end

    def self_time
      @self_time ||= ms(elapsed - children.inject(0) {|sum,el| sum += el.elapsed}).to_s
    end

    def total_time
      ms(elapsed)
    end
  end
end

class Module
  def instrument(*meths)
    options = Hash === meths.last ? meths.pop : {}
{'fraction_non_alphanumeric': 0.13176244289492667, 'fraction_numerical': 0.0038470786246693916, 'mean_word_length': 2.237354085603113, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3990492', 'n_tokens_mistral': 1377, 'n_tokens_neox': 1340, 'n_words': 322}