rubyperf 0.0.0
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/.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
|