starttime 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/starttime +167 -0
- data/templates/file.html.erb +15 -0
- data/templates/template.html.erb +27 -0
- metadata +55 -0
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
|
+
|