rubyperf 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +11 -0
- data/.idea/modules.xml +9 -0
- data/.idea/rubyperf.iml +15 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +31 -0
- data/README.rdoc +35 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/perf/meter.rb +374 -0
- data/lib/perf/meter_factory.rb +47 -0
- data/lib/perf/no_op_meter.rb +39 -0
- data/lib/perf/noop_measure.rb +39 -0
- data/lib/perf/report_format.rb +130 -0
- data/lib/perf/report_format_html.rb +34 -0
- data/lib/perf/report_format_simple.rb +67 -0
- data/lib/rubyperf.rb +154 -0
- data/test/helper.rb +24 -0
- data/test/perf_test_example.rb +19 -0
- data/test/rubyperf_test_helpers.rb +43 -0
- data/test/test_perf_meter.rb +230 -0
- metadata +150 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
module Perf
|
7
|
+
#
|
8
|
+
# This class can be used in substitution to a Perf::Measure class to avoid overhead when performance measurments is not
|
9
|
+
# required. It needs to maintain the same API as Perf::Measure.
|
10
|
+
#
|
11
|
+
class NoopMeasure
|
12
|
+
|
13
|
+
def measurements
|
14
|
+
{}
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_stack
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(logger = nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear
|
25
|
+
end
|
26
|
+
|
27
|
+
#############################################################################################################
|
28
|
+
|
29
|
+
def measure(what,type=nil)
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
|
33
|
+
def count_value(what_to_count)
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
module Perf
|
7
|
+
|
8
|
+
#
|
9
|
+
# Base class for all the standard formatting options for a Perf::Meter. Provies a simple interface to create
|
10
|
+
# custom views of the performance report.
|
11
|
+
#
|
12
|
+
class ReportFormat
|
13
|
+
|
14
|
+
MIN_TOTAL_TIME = 1.0e-10
|
15
|
+
|
16
|
+
# Format takes a Perf::Meter plus a hash of options and converts it into a header, followed by a series
|
17
|
+
# of entries in a hash format that can be easily converted in any other format such as Text, HTML, XML, etc.
|
18
|
+
#
|
19
|
+
# You call this method every time that you want to generate a report from a Perf::Meter object.
|
20
|
+
#
|
21
|
+
# ==== Options
|
22
|
+
#
|
23
|
+
# * +:max_count_len+ : Maximum expected length of a block/espresson/method count.
|
24
|
+
#
|
25
|
+
|
26
|
+
def format(perf,options={})
|
27
|
+
options[:max_count_len] ||= 6
|
28
|
+
rep=[]
|
29
|
+
percents={}
|
30
|
+
|
31
|
+
max_count=options[:max_count_len]
|
32
|
+
max_title=0
|
33
|
+
keys_in_order=perf.measurements.keys.sort
|
34
|
+
total = Benchmark::Tms.new
|
35
|
+
|
36
|
+
perf.measurements.each_pair do |what,m|
|
37
|
+
title_len=format_title(what,options).length
|
38
|
+
path = what.split("\\")
|
39
|
+
|
40
|
+
max_title = title_len if title_len>max_title
|
41
|
+
max_count = m[:count].to_s.length if m[:count].to_s.length>max_count
|
42
|
+
|
43
|
+
total += m[:time] if path.size==2 # This calculates the max of the level-1 entries needed for the root entry.
|
44
|
+
end
|
45
|
+
|
46
|
+
totals=[total.real]
|
47
|
+
depth=1
|
48
|
+
keys_in_order.each do |what|
|
49
|
+
m=perf.measurements[what]
|
50
|
+
path = what.split("\\")
|
51
|
+
if path.size-1 != depth
|
52
|
+
if path.size-1 > depth
|
53
|
+
totals.push 0
|
54
|
+
else
|
55
|
+
totals.pop(depth-(path.size-1))
|
56
|
+
end
|
57
|
+
depth=path.size-1
|
58
|
+
end
|
59
|
+
totals[totals.size-1] = m[:time].real
|
60
|
+
totals[totals.size-1] = MIN_TOTAL_TIME if totals[totals.size-1]<MIN_TOTAL_TIME
|
61
|
+
percents[what]=(m[:time].real*100.0)/totals[totals.size-2]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Header
|
65
|
+
rep << format_header(:title => "measure path", :max_title => max_title,
|
66
|
+
:percent => "percent",
|
67
|
+
:count => "count", :max_count => max_count,
|
68
|
+
:time => Benchmark::Tms::CAPTION,
|
69
|
+
:options => options)
|
70
|
+
|
71
|
+
# Root
|
72
|
+
|
73
|
+
# Split of keys
|
74
|
+
keys_in_order.each do |what|
|
75
|
+
m=perf.measurements[what]
|
76
|
+
title = format_title(what,options)
|
77
|
+
rep << format_measure(:title => title, :max_title => max_title,
|
78
|
+
:percent => percents[what]||0.0,
|
79
|
+
:count => m[:count], :max_count => max_count,
|
80
|
+
:time => m[:time],
|
81
|
+
:options => options)
|
82
|
+
end
|
83
|
+
|
84
|
+
rep << format_footer(options)
|
85
|
+
rep
|
86
|
+
end
|
87
|
+
|
88
|
+
# Override to format the output of a single measure. Returns the measure in whatever format the output needs to be.
|
89
|
+
#
|
90
|
+
# ==== Options
|
91
|
+
#
|
92
|
+
# * +v+ : Hash containing the following keys:
|
93
|
+
# +title+ : Title - or path - of the block/method/expression (\root\a\b\c\d\something))
|
94
|
+
# +max_title+ : Longest title in the report
|
95
|
+
# +percent+ : Percentage of time spent in this measure compared to the containing block.
|
96
|
+
# +count+ : How many times the block/method/exression was executed
|
97
|
+
# +time+ : Execution time expressed as a Benchmark::Tms value; For titles this is Benchmark::Tms::CAPTION
|
98
|
+
# +options+ : Formatting options, as passed by the framework or the user.
|
99
|
+
#
|
100
|
+
|
101
|
+
def format_measure(v)
|
102
|
+
v
|
103
|
+
end
|
104
|
+
|
105
|
+
# Override to format the output of the header of the data.
|
106
|
+
#
|
107
|
+
# See format_measure
|
108
|
+
|
109
|
+
def format_header(v)
|
110
|
+
format_measure(v)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Override to format the output of the header of the data.
|
114
|
+
#
|
115
|
+
# See format_measure
|
116
|
+
|
117
|
+
def format_title(what,options)
|
118
|
+
what
|
119
|
+
end
|
120
|
+
|
121
|
+
# Override to format the output of the footer of the data.
|
122
|
+
#
|
123
|
+
# See format_measure
|
124
|
+
|
125
|
+
def format_footer(options)
|
126
|
+
""
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rubyperf'
|
7
|
+
require 'cgi'
|
8
|
+
|
9
|
+
module Perf
|
10
|
+
class ReportFormatHtml < ReportFormat
|
11
|
+
|
12
|
+
PERCENT_FORMAT = "%.3f"
|
13
|
+
INDENT = " "*3
|
14
|
+
|
15
|
+
def format_header(v)
|
16
|
+
"<table class='rubyperf_report_format_html_table'><tr><th>#{v[:title]}</th><th>%</th><th>count</th><th>user</th><th>system</th><th>total</th><th>real</th></tr>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def format_measure(v)
|
20
|
+
percent= v[:percent].is_a?(String) ? v[:percent] : (PERCENT_FORMAT%v[:percent])
|
21
|
+
"<tr><td>#{v[:title]}</td><td>#{percent}</td><td>#{v[:count]}</td><td>#{v[:time].utime}</td><td>#{v[:time].stime}</td><td>#{v[:time].total}</td><td>#{v[:time].real}</td></td>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def format_footer(v)
|
25
|
+
"</table>"
|
26
|
+
end
|
27
|
+
|
28
|
+
def format_title(what,options)
|
29
|
+
path=what.split("\\")
|
30
|
+
"#{(path.size-2) ? INDENT*(path.size-2) : ""}\\#{CGI.escapeHTML(path.last)}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rubyperf'
|
7
|
+
|
8
|
+
module Perf
|
9
|
+
# Formats the report this way:
|
10
|
+
#
|
11
|
+
# measure path : percent% count user system total real
|
12
|
+
# \ : 100.000% 1 2.540000 0.030000 2.570000 ( 4.602187)
|
13
|
+
# \emtpy_loop : 0.042% 1 0.000000 0.000000 0.000000 ( 0.001946)
|
14
|
+
# \measure_overhead_x10000 : 5.893% 1 0.260000 0.010000 0.270000 ( 0.271223)
|
15
|
+
# \nothing1 : 90.286% 1000 0.250000 0.010000 0.260000 ( 0.244876)
|
16
|
+
# \blah2 : 2.685% 1000 0.010000 0.000000 0.010000 ( 0.006574)
|
17
|
+
# \nothing2 : 74.104% 1000 0.120000 0.010000 0.130000 ( 0.181462)
|
18
|
+
# \blah3 : 4.020% 1000 0.010000 0.000000 0.010000 ( 0.007294)
|
19
|
+
# \nothing3 : 3.679% 1000 0.070000 0.000000 0.070000 ( 0.006676)
|
20
|
+
# \zzzzblah3 : 3.716% 1000 0.000000 0.000000 0.000000 ( 0.006744)
|
21
|
+
# \something : 11.144% 1 0.000000 0.000000 0.000000 ( 0.512861)
|
22
|
+
# \something1 : 39.077% 1 0.000000 0.000000 0.000000 ( 0.200411)
|
23
|
+
# \something2 : 60.864% 2 0.000000 0.000000 0.000000 ( 0.312149)
|
24
|
+
# \string_operations : 20.097% 2 0.910000 0.000000 0.910000 ( 0.924894)
|
25
|
+
# \ciao1000 : 50.085% 1 0.460000 0.000000 0.460000 ( 0.463233)
|
26
|
+
# \help1000 : 49.893% 1 0.450000 0.000000 0.450000 ( 0.461461)
|
27
|
+
# \test = "1" : 21.737% 1 0.000000 0.000000 0.000000 ( 1.000368)
|
28
|
+
# \test = "false" : 0.000% 2 0.000000 0.000000 0.000000 ( 0.000015)
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# Where:
|
32
|
+
#
|
33
|
+
# percent% : is the percentage of the real time of the real time of its containing path.
|
34
|
+
# For example blah2 is 2.685% of the real time of nothing1.The sum of the percentages at the same depth
|
35
|
+
# should always be < 100% (for example depth2 1 is 0.042+5.893+11.144+20.097+21.737 = 58.913). The rest
|
36
|
+
# is unmeasured time spent.
|
37
|
+
# count : is the number of time the measure was taken. All the measures are the cumulative elapsed time for all
|
38
|
+
# the measures. For example blah3 numbers refer to the cumulative time spent in 1000 execution of that block.
|
39
|
+
# user : User CPU time
|
40
|
+
# system : System CPU time
|
41
|
+
# total : user+system
|
42
|
+
# real : Real time
|
43
|
+
#
|
44
|
+
|
45
|
+
class ReportFormatSimple < ReportFormat
|
46
|
+
|
47
|
+
DEFAULT_INDENT = " "
|
48
|
+
PERCENT_FORMAT = "%.3f"
|
49
|
+
EXTRA_SPACES_AFTER_TITLE = 2
|
50
|
+
|
51
|
+
def format(perf,options={})
|
52
|
+
options[:indent] ||= DEFAULT_INDENT
|
53
|
+
super perf,options
|
54
|
+
end
|
55
|
+
|
56
|
+
def format_measure(v)
|
57
|
+
percent= v[:percent].is_a?(String) ? v[:percent] : (PERCENT_FORMAT%v[:percent])
|
58
|
+
"#{v[:title].ljust(v[:max_title]+EXTRA_SPACES_AFTER_TITLE," ")}: #{percent.rjust(7," ")}% #{v[:count].to_s.rjust(v[:max_count]," ")} #{v[:time].to_s.gsub(/\n/,'')}\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def format_title(what,options)
|
62
|
+
path=what.split("\\")
|
63
|
+
"#{(path.size-2) ? options[:indent]*(path.size-2) : ""}\\#{path.last}"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/rubyperf.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
#
|
4
|
+
# Project home-page git repository:
|
5
|
+
# https://github.com/lpasqualis/rubyperf
|
6
|
+
#
|
7
|
+
# Author can be contacted at:
|
8
|
+
# lpasqualis@gmail.com
|
9
|
+
#
|
10
|
+
# Author's Blog:
|
11
|
+
# http://www.lorenzopasqualis.com
|
12
|
+
#
|
13
|
+
# License:
|
14
|
+
#
|
15
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
16
|
+
# a copy of this software and associated documentation files (the
|
17
|
+
# "Software"), to deal in the Software without restriction, including
|
18
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
19
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
20
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
21
|
+
# the following conditions:
|
22
|
+
#
|
23
|
+
# The above copyright notice and this permission notice shall be
|
24
|
+
# included in all copies or substantial portions of the Software.
|
25
|
+
#
|
26
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
27
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
28
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
29
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
30
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
31
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
32
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
33
|
+
#
|
34
|
+
#############################################################################
|
35
|
+
#
|
36
|
+
# This gem measures the execution time of blocks of code, methods and expressions.
|
37
|
+
# It generates detailed reports in various formats showing the nested structure
|
38
|
+
# of the measures.
|
39
|
+
#
|
40
|
+
# Designed to give tools to drill in the performance of hot code and identify
|
41
|
+
# bottlenecks.
|
42
|
+
#
|
43
|
+
# Currently available output formats for the report: text, html.
|
44
|
+
#
|
45
|
+
# Example of use:
|
46
|
+
#
|
47
|
+
# require 'rubyperf'
|
48
|
+
#
|
49
|
+
# def example
|
50
|
+
# m=Perf::Meter.new
|
51
|
+
# m.measure(:string_operations) do
|
52
|
+
# m.measure(:ciao) do
|
53
|
+
# 1000.times do; "CIAO"*100; end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# m.measure(:string_operations) do
|
57
|
+
# m.measure(:help) do
|
58
|
+
# 1000.times do; "HELP"*100; end
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
# m.measure(:emtpy_loop) do
|
62
|
+
# 50000.times do; end;
|
63
|
+
# end
|
64
|
+
# m.measure(:rough_overhead_x10000) do
|
65
|
+
# 1000.times do
|
66
|
+
# m.measure(:block_1) do
|
67
|
+
# m.measure(:block_1_1) do
|
68
|
+
# end
|
69
|
+
# m.measure(:block_1_2) do
|
70
|
+
# m.measure(:block_1_2_1) do
|
71
|
+
# end
|
72
|
+
# m.measure(:block_1_2_2) do
|
73
|
+
# end
|
74
|
+
# m.measure(:block_1_2_3) do
|
75
|
+
# m.measure_result(:bool_exp_1_2_3) { false }
|
76
|
+
# m.measure_result(:bool_exp_1_2_3) { true }
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# m.measure(:sleep1) do
|
84
|
+
# m.measure(:sleep1_1) do
|
85
|
+
# sleep(0.01)
|
86
|
+
# end
|
87
|
+
# m.measure(:sleep_1_2) do
|
88
|
+
# sleep(0.02)
|
89
|
+
# end
|
90
|
+
# m.measure(:sleep_1_3) do
|
91
|
+
# sleep(0.03)
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# m.measure(:empty) do
|
95
|
+
# end
|
96
|
+
# m.measure_result("test") { sleep(1) }
|
97
|
+
# m.measure_result("test") { false }
|
98
|
+
# m.measure_result("test") { false }
|
99
|
+
#
|
100
|
+
# m.method_meters(Array,[:sort,:reverse],[:new]) do
|
101
|
+
# Array.new(1000000,"abc").reverse.sort
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# puts m.report_simple
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# This sample outputs the following report (see notes)).
|
108
|
+
#
|
109
|
+
# measure path : percent% count user system total real
|
110
|
+
#
|
111
|
+
# \blocks : 100.000% 8014 1.040000 0.060000 1.100000 ( 2.167488)
|
112
|
+
# \empty : 0.000% 1 0.000000 0.000000 0.000000 ( 0.000005)
|
113
|
+
# \emtpy_loop : 0.130% 1 0.010000 0.000000 0.010000 ( 0.002825)
|
114
|
+
# \rough_overhead_x10000 : 49.354% 1 1.000000 0.060000 1.060000 ( 1.069733)
|
115
|
+
# \block_1 : 92.013% 1000 0.890000 0.050000 0.940000 ( 0.984297)
|
116
|
+
# \block_1_1 : 0.503% 1000 0.020000 0.000000 0.020000 ( 0.004951)
|
117
|
+
# \block_1_2 : 77.414% 1000 0.670000 0.040000 0.710000 ( 0.761979)
|
118
|
+
# \block_1_2_1 : 0.640% 1000 0.000000 0.010000 0.010000 ( 0.004880)
|
119
|
+
# \block_1_2_2 : 0.644% 1000 0.010000 0.000000 0.010000 ( 0.004904)
|
120
|
+
# \block_1_2_3 : 48.027% 1000 0.370000 0.020000 0.390000 ( 0.365958)
|
121
|
+
# \bool_exp_1_2_3 = "false" : 1.354% 1000 0.000000 0.000000 0.000000 ( 0.004956)
|
122
|
+
# \bool_exp_1_2_3 = "true" : 1.369% 1000 0.020000 0.000000 0.020000 ( 0.005012)
|
123
|
+
# \sleep1 : 2.868% 1 0.000000 0.000000 0.000000 ( 0.062157)
|
124
|
+
# \sleep1_1 : 17.808% 1 0.000000 0.000000 0.000000 ( 0.011069)
|
125
|
+
# \sleep_1_2 : 32.524% 1 0.000000 0.000000 0.000000 ( 0.020216)
|
126
|
+
# \sleep_1_3 : 49.090% 1 0.000000 0.000000 0.000000 ( 0.030513)
|
127
|
+
# \string_operations : 1.468% 2 0.030000 0.000000 0.030000 ( 0.031817)
|
128
|
+
# \ciao : 95.276% 1 0.030000 0.000000 0.030000 ( 0.030314)
|
129
|
+
# \help : 4.111% 1 0.000000 0.000000 0.000000 ( 0.001308)
|
130
|
+
# \test = "1" : 46.160% 1 0.000000 0.000000 0.000000 ( 1.000502)
|
131
|
+
# \test = "false" : 0.000% 2 0.000000 0.000000 0.000000 ( 0.000008)
|
132
|
+
# \methods : 100.000% 3 0.140000 0.010000 0.150000 ( 0.154880)
|
133
|
+
# \#<Class:Array> : 21.416% 1 0.030000 0.010000 0.040000 ( 0.033169)
|
134
|
+
# \new : 99.907% 1 0.030000 0.010000 0.040000 ( 0.033138)
|
135
|
+
# \Array : 78.489% 2 0.110000 0.000000 0.110000 ( 0.121563)
|
136
|
+
# \reverse : 38.671% 1 0.040000 0.000000 0.040000 ( 0.047010)
|
137
|
+
# \sort : 61.287% 1 0.070000 0.000000 0.070000 ( 0.074502)
|
138
|
+
#
|
139
|
+
#
|
140
|
+
# Note: the percentage in each line is calculated on the real time of the containing block. For example in the example
|
141
|
+
# -> block_1_1 takes 0.503% of the real time of block_1
|
142
|
+
# -> block_1_2 takes 77.414% of the real time of block
|
143
|
+
#
|
144
|
+
# TODO:
|
145
|
+
#
|
146
|
+
# * Eliminate the overhead of the perf meter operations from the computation of times.
|
147
|
+
#
|
148
|
+
|
149
|
+
require 'perf/meter'
|
150
|
+
require 'perf/meter_factory'
|
151
|
+
require 'perf/no_op_meter'
|
152
|
+
require 'perf/report_format'
|
153
|
+
require 'perf/report_format_simple'
|
154
|
+
require 'perf/report_format_html'
|
data/test/helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'bundler'
|
8
|
+
begin
|
9
|
+
Bundler.setup(:default, :development)
|
10
|
+
rescue Bundler::BundlerError => e
|
11
|
+
$stderr.puts e.message
|
12
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
13
|
+
exit e.status_code
|
14
|
+
end
|
15
|
+
require 'test/unit'
|
16
|
+
require 'shoulda'
|
17
|
+
|
18
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
19
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
20
|
+
require 'rubyperf'
|
21
|
+
|
22
|
+
class Test::Unit::TestCase
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
class PerfTestExample
|
7
|
+
def test(a,b,c)
|
8
|
+
(0..100000).to_a.reverse.reverse.reverse # Do something heavy
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_np
|
12
|
+
(0..300000).to_a.reverse.reverse.reverse # Do something heavy
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.static_method
|
16
|
+
(0..300000).to_a.reverse.reverse.reverse # Do something heavy
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 Lorenzo Pasqualis - DreamBox Learning, Inc
|
3
|
+
# https://github.com/lpasqualis/rubyperf
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rubyperf'
|
7
|
+
require 'perf_test_example'
|
8
|
+
|
9
|
+
class RubyperfTestHelpers
|
10
|
+
def self.get_measure
|
11
|
+
m=Perf::Meter.new
|
12
|
+
|
13
|
+
a=PerfTestExample.new
|
14
|
+
m.measure(:measure_test) { a.test(1,2,3) }
|
15
|
+
m.measure(:measure_test_np) { a.test_np }
|
16
|
+
m.measure(:some_expressions) do
|
17
|
+
m.measure_result(:expression1) { 1234+12345 }
|
18
|
+
m.measure_result(:expression1) { 1234-123 }
|
19
|
+
m.measure_result(:expression2) { "string" }
|
20
|
+
end
|
21
|
+
# Then use the instance method
|
22
|
+
m.method_meters(PerfTestExample,[:test,:test_np],[:static_method]) do
|
23
|
+
a=PerfTestExample.new
|
24
|
+
a.test(1,2,3)
|
25
|
+
a.test_np
|
26
|
+
PerfTestExample.static_method
|
27
|
+
end
|
28
|
+
m
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.verify_report(m,expected_paths)
|
32
|
+
rf=Perf::ReportFormat.new
|
33
|
+
r=rf.format(m)
|
34
|
+
cnt=0
|
35
|
+
expected_paths.each do |ep|
|
36
|
+
r.each do |l|
|
37
|
+
cnt+=1 if l[:title]==ep
|
38
|
+
end
|
39
|
+
end
|
40
|
+
cnt==expected_paths.size
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|