lib/hotch/memory.rb in hotch-0.6.0 vs lib/hotch/memory.rb in hotch-0.7.0

- old
+ new

@@ -1,9 +1,12 @@ -require 'allocation_tracer' +# frozen_string_literal: true +require "allocation_tracer" +require "stringio" + class Hotch - def self.memory(name: $0, aggregate: true, &block) + def self.memory(name: $PROGRAM_NAME, aggregate: true, &block) memory = if aggregate $hotch_memory ||= Memory.new(name) else caller = Kernel.caller_locations(1).first name = "#{name}:#{caller.path}:#{caller.lineno}" @@ -27,39 +30,42 @@ @started = nil @disable_gc = disable_gc end def self.report(name, **args, &block) - new(name, **args).run(&block).report + hotch = new(name, **args) + hotch.run(&block) + hotch.report end def start return if @started + GC.disable if @disable_gc - ObjectSpace::AllocationTracer.setup [:path, :line, :type] + ObjectSpace::AllocationTracer.setup %i[path line type] ObjectSpace::AllocationTracer.start @started = true end def stop return unless @started + results = ObjectSpace::AllocationTracer.stop @started = nil GC.enable if @disable_gc @reports << Report.new(results, @ignore_paths) end def run start yield - self ensure stop end def report - # TODO make it persistent (as CSV) + # TODO: make it persistent (as CSV) report = @reports.inject(:+) @reports.clear if block_given? yield report @@ -83,11 +89,11 @@ end private def name - @name.gsub(/\W+/, '_') + @name.gsub(/\W+/, "_") end class Report attr_reader :lines @@ -97,24 +103,24 @@ Line.from_result(result, ignore_paths) end.compact end def +(other) - by_key = Hash[@lines.map { |line| [line.key, line] }] + by_key = @lines.to_h { |line| [line.key, line] } other.lines.each do |line| - if existing = by_key[line.key] + if (existing = by_key[line.key]) existing.sum(line) else by_key[line.key] = line @lines << line end end self end def format - # TODO refactor + # TODO: refactor max_lengths = Array.new(Line.members.size, 0) ([@header, @total] + @lines).each do |line| line.lengths.each.with_index do |length, i| max_lengths[i] = length if length > max_lengths[i] end @@ -134,29 +140,24 @@ io = StringIO.new puts(io) io.string end - private def total! - return if defined? @total - - @total = Line::Total.new - @lines.each do |line| - @total.sum(line) - end - end - + # rubocop:disable Style/StructInheritance class Line < Struct.new(:filename, :type, :count, :old_count, :total_age, :min_age, :max_age, :total_memsize) + # rubocop:enable Style/StructInheritance + # [ # [path, lineno, type], # [count, old_count, total_age, min_age, max_age, total_memsize] # ] def self.from_result(result, ignore_paths) path, line, *args = result.flatten(1) return if ignore_paths.any? { |ip| ip == path || ip === path } - filename = "#{strip_path(path || "?")}:#{line}" + + filename = "#{strip_path(path)}:#{line}" new(filename, *args) end def key [filename, type] @@ -175,27 +176,38 @@ other.to_a.each.with_index do |value, i| self[i] += value if Numeric === value end end - private - MAX_PATH_LENGTH = 50 def self.strip_path(path) + return "?" unless path + strip = %r{#{Regexp.union($LOAD_PATH)}/?} path.gsub!(strip, "") if path.size > MAX_PATH_LENGTH + 3 - # TODO Refactor - "..." + path[-MAX_PATH_LENGTH..-1] + # TODO: Refactor + "...#{path[-MAX_PATH_LENGTH..]}" else path end end class Total < Line def initialize super("TOTAL", "", 0, 0, 0, 0, 0, 0) end + end + end + + private + + def total! + return if defined? @total + + @total = Line::Total.new + @lines.each do |line| + @total.sum(line) end end end end end