bahuvrihi (owner)

Revisions

gist: 5732 Download_button fork
public
Description:
A load time profiler script
Public Clone URL: git://gist.github.com/5732.git
Embed All Files: show embed
profile_load_time.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# = Description
# A load time profiler script, useful for identifying requires
# that slow down the loading of a script.
#
# Oftentimes we use but don't always need what we require in
# scripts. This can dramatically slow load times, which can be
# annoying. Use this script to identify slow-loading parts of
# a script and then consider using autoloading to defer
# the require until you really need it.
#
# #require 'stringio'
# autoload(:StringIO, 'stringio')
#
# = Usage
#
# Simply cut-n-paste this script before your first require
# statements (or add the requires at the end of this script):
#
# [profile_load_time.rb ]
# # ... this script ...
#
# require 'time'
#
# Then from the command line:
#
# % ruby profile_load_time.rb
# ================================================================================
# Require/Load Profile (time in ms)
# * Load times > 0.5 ms
# - duplicate requires
# ================================================================================
# * 9.1: time
# * 5.2: parsedate
# * 5.0: date/format
# * 1.2: rational
#
# Total time: 9.105 ms
#
# = Info
# Developer:: Simon Chiang (http://bahuvrihi.wordpress.com)
# Licence:: MIT-Style (http://en.wikipedia.org/wiki/MIT_License)
# Gist:: http://gist.github.com/5732
 
class RecursiveProfile
  class << self
    def instance
      @@instance
    end
    
    def [](key)
      @@variables[key]
    end
    
    def []=(key, value)
      @@variables[key] = value
    end
  end
  
  attr_reader :results
 
  def initialize
    @results = []
  end
  
  def profile
    current = @results
    @results = []
    
    start = Time.now
    target = [yield]
    target << Time.now-start
    target << @results
    
    @results = current
    @results << target
  end
  
  def each
    recurse(@results, 0) do |value, time, nesting_depth|
      yield(value, time, nesting_depth)
    end
  end
  
  private
 
  def recurse(parent, nesting_depth, &block)
    parent.each do |value, time, children|
      yield(value, time, nesting_depth)
      recurse(children, nesting_depth + 1, &block)
    end
  end
  
  @@instance = RecursiveProfile.new
  @@variables = {}
end
 
def require(path)
  RecursiveProfile.instance.profile do
    begin
      super
      path
    rescue(Exception)
      "#{path} (error: #{$!.message})"
    end
  end
end
 
def load(path)
  RecursiveProfile.instance.profile do
    begin
      super
      path
    rescue(Exception)
      "#{path} (error: #{$!.message})"
    end
  end
end
 
at_exit do
  total_time = (Time.now - RecursiveProfile[:start]) * 10**3
  
  values = []
  duplicates = []
  RecursiveProfile.instance.each do |value, time, nesting_depth|
    (values.include?(value) ? duplicates : values) << value
  end
  
  puts "=" * 80
  puts "Require/Load Profile (time in ms)"
  puts "* Load time > #{RecursiveProfile[:cutoff_in_ms]} ms"
  puts "- Duplicate require"
  puts "=" * 80
  RecursiveProfile.instance.each do |value, time, nesting_depth|
    time_in_ms = time * 10**3
    flags = (time_in_ms > RecursiveProfile[:cutoff_in_ms] ? '*' : ' ')
    
    flags = "-" if duplicates.include?(value) && !values.include?(value)
    values.delete(value)
 
    puts "#{flags} #{' ' * nesting_depth}#{"%.1f" % time_in_ms}: #{value}"
  end
 
  puts
  puts "Total time: #{total_time} ms"
end
 
RecursiveProfile[:cutoff_in_ms] = 0.5
RecursiveProfile[:start] = Time.now
 
###############################################################################
# add requires here
###############################################################################