starttime 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/starttime ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'erb'
4
+
5
+ options = {
6
+ :output_format => 'flat'
7
+ }
8
+ files = []
9
+
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "Usage: starttime [options] file(s)"
12
+
13
+ opts.on "-r", "--rails", "Profile environment time for a Rails project. Implies config/environment as a file to require" do
14
+ files << 'config/environment'
15
+ end
16
+
17
+ opts.on "-o", "--output=FILENAME", "Output to FILENAME. Default is STDOUT." do |filename|
18
+ options[:output_file] = filename
19
+ end
20
+
21
+ opts.on "-f", "--format=FORMAT", "Choose output format. Available are html and flat." do |format|
22
+ options[:output_format] = format
23
+ end
24
+
25
+ opts.on "-e", "--execute=COMMAND", "Execute a Ruby command" do |command|
26
+ options[:command] = command
27
+ end
28
+ end
29
+
30
+ opts.parse!(ARGV)
31
+
32
+ unless options[:command]
33
+ files += ARGV unless ARGV.empty?
34
+
35
+ if files.empty?
36
+ puts opts.help
37
+ exit
38
+ end
39
+ end
40
+
41
+ class SourceFile
42
+ attr_accessor :name, :duration
43
+
44
+ def initialize(name)
45
+ @name = name
46
+ end
47
+
48
+ def children
49
+ @children ||= []
50
+ end
51
+
52
+ def children_sorted_by_duration
53
+ children.sort_by { |c| c.duration }.reverse
54
+ end
55
+
56
+ def own_time
57
+ duration - children.collect { |c| c.duration }.sum rescue 0
58
+ end
59
+
60
+ class BasePrinter
61
+ def initialize(file, output)
62
+ @file = file
63
+ @output = output
64
+ end
65
+ end
66
+
67
+ class FlatPrinter < BasePrinter
68
+ def print
69
+ print_with_indent(0, @file)
70
+ end
71
+
72
+ def print_with_indent(num, file)
73
+ @output.puts((" " * num) + "#{file.name} (#{file.duration})")
74
+ file.children_sorted_by_duration.each do |child|
75
+ print_with_indent(num + 2, child)
76
+ end
77
+ end
78
+ end
79
+
80
+ class HTMLPrinter < BasePrinter
81
+ TEMPLATE_PATH = File.dirname(__FILE__) + '/../templates'
82
+
83
+ def print
84
+ @output.puts render("#{TEMPLATE_PATH}/template.html.erb")
85
+ end
86
+
87
+ def render(filename, vars = {})
88
+ b = binding
89
+ vars.each do |name, var|
90
+ eval("#{name}=vars[:#{name}]", b)
91
+ end
92
+ ERB.new(File.read(filename)).result(b)
93
+ end
94
+ end
95
+ end
96
+
97
+ $current_source_file = SourceFile.new(__FILE__)
98
+
99
+ module Kernel
100
+ def require_with_benchmark(*args)
101
+ old_source_file = $current_source_file
102
+
103
+ file_name = args.first
104
+
105
+ $current_source_file = current_source_file = SourceFile.new(file_name)
106
+
107
+ before = Time.now.to_f
108
+ result = require_without_benchmark(*args)
109
+ ensure
110
+ after = Time.now.to_f
111
+
112
+ current_source_file.duration = after - before
113
+ old_source_file.children << current_source_file
114
+
115
+ $current_source_file = old_source_file
116
+
117
+ result
118
+ end
119
+
120
+ alias require_without_benchmark require
121
+ alias require require_with_benchmark
122
+
123
+ def load_with_benchmark(*args)
124
+ old_source_file = $current_source_file
125
+
126
+ file_name = args.first
127
+
128
+ $current_source_file = current_source_file = SourceFile.new(file_name)
129
+
130
+ before = Time.now.to_f
131
+ result = load_without_benchmark(*args)
132
+ ensure
133
+ after = Time.now.to_f
134
+
135
+ current_source_file.duration = after - before
136
+ old_source_file.children << current_source_file
137
+
138
+ $current_source_file = old_source_file
139
+ result
140
+ end
141
+
142
+ alias load_without_benchmark load
143
+ alias load load_with_benchmark
144
+ end
145
+
146
+ if options[:command]
147
+ eval(options[:command])
148
+ else
149
+ files.each do |file|
150
+ require file
151
+ end
152
+ end
153
+
154
+ output_stream = if options[:output_file]
155
+ File.open(options[:output_file], 'w')
156
+ else
157
+ $stdout
158
+ end
159
+
160
+ case options[:output_format]
161
+ when 'html'
162
+ SourceFile::HTMLPrinter.new($current_source_file, output_stream).print
163
+ when 'flat'
164
+ SourceFile::FlatPrinter.new($current_source_file, output_stream).print
165
+ end
166
+
167
+ output_stream.close
@@ -0,0 +1,15 @@
1
+ <% if file.children.empty? %>
2
+ <%= file.name.gsub(Dir.pwd, '$PWD') %> (<%= (file.duration * 1000).to_i %> ms)
3
+ <% else %>
4
+ <a href='#'><%= file.name.gsub(Dir.pwd, '$PWD') %></a>
5
+ <% if file.duration %>
6
+ (total <%= (file.duration * 1000).to_i %> ms, own <%= (file.own_time * 1000).to_i %> ms)
7
+ <% end %>
8
+ <ul style='display:none'>
9
+ <% file.children_sorted_by_duration.each do |child| %>
10
+ <li>
11
+ <%= render "#{TEMPLATE_PATH}/file.html.erb", :file => child %>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
4
+ <head>
5
+ <style>
6
+ .report ul li { list-style: none; padding: 2px 0 2px 20px; text-indent: -19px; background-position: 9px 0; }
7
+ .report ul li > * { text-indent: 0px; }
8
+ </style>
9
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script>
10
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js"></script>
11
+ <script>
12
+ $(document).observe('dom:loaded', function() {
13
+ $('report').getElementsBySelector('a').each(function(link) {
14
+ link.observe('click', function(event) {
15
+ Effect.toggle(link.up().down('ul'), 'blind', { duration: 0.3 });
16
+ event.stop();
17
+ });
18
+ });
19
+ });
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <div id="report" class="report">
24
+ <%= render "#{TEMPLATE_PATH}/file.html.erb", :file => @file %>
25
+ </div>
26
+ </body>
27
+ </html>
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: starttime
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Kadauke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-07 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: tkadauke@imedo.de
18
+ executables:
19
+ - starttime
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - bin/starttime
26
+ - templates/file.html.erb
27
+ - templates/template.html.erb
28
+ has_rdoc: false
29
+ homepage: http://www.imedo.de/
30
+ post_install_message:
31
+ rdoc_options: []
32
+
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: "0"
40
+ version:
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ requirements: []
48
+
49
+ rubyforge_project:
50
+ rubygems_version: 1.3.1
51
+ signing_key:
52
+ specification_version: 2
53
+ summary: Instrument startup time of Ruby applications
54
+ test_files: []
55
+