hitimes 1.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +69 -0
- data/LICENSE +13 -0
- data/README +134 -0
- data/Rakefile +66 -0
- data/examples/benchmarks.rb +113 -0
- data/examples/stats.rb +31 -0
- data/ext/hitimes/extconf.rb +17 -0
- data/ext/hitimes/hitimes_ext.c +21 -0
- data/ext/hitimes/hitimes_instant_clock_gettime.c +28 -0
- data/ext/hitimes/hitimes_instant_osx.c +16 -0
- data/ext/hitimes/hitimes_instant_windows.c +27 -0
- data/ext/hitimes/hitimes_interval.c +362 -0
- data/ext/hitimes/hitimes_interval.h +73 -0
- data/ext/hitimes/hitimes_stats.c +269 -0
- data/ext/hitimes/hitimes_stats.h +30 -0
- data/ext/java/src/hitimes/Hitimes.java +54 -0
- data/ext/java/src/hitimes/HitimesInterval.java +174 -0
- data/ext/java/src/hitimes/HitimesService.java +16 -0
- data/ext/java/src/hitimes/HitimesStats.java +112 -0
- data/gemspec.rb +65 -0
- data/lib/hitimes.rb +37 -0
- data/lib/hitimes/hitimes.jar +0 -0
- data/lib/hitimes/metric.rb +118 -0
- data/lib/hitimes/mutexed_stats.rb +32 -0
- data/lib/hitimes/paths.rb +53 -0
- data/lib/hitimes/stats.rb +58 -0
- data/lib/hitimes/timed_metric.rb +176 -0
- data/lib/hitimes/timed_value_metric.rb +233 -0
- data/lib/hitimes/value_metric.rb +71 -0
- data/lib/hitimes/version.rb +57 -0
- data/spec/interval_spec.rb +133 -0
- data/spec/metric_spec.rb +30 -0
- data/spec/mutex_stats_spec.rb +34 -0
- data/spec/paths_spec.rb +13 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/stats_spec.rb +100 -0
- data/spec/timed_metric_spec.rb +155 -0
- data/spec/timed_value_metric_spec.rb +172 -0
- data/spec/value_metric_spec.rb +110 -0
- data/spec/version_spec.rb +33 -0
- data/tasks/announce.rake +42 -0
- data/tasks/config.rb +109 -0
- data/tasks/distribution.rake +93 -0
- data/tasks/documentation.rake +32 -0
- data/tasks/extension.rake +108 -0
- data/tasks/rspec.rake +33 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/utils.rb +80 -0
- metadata +191 -0
data/HISTORY
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= Changelog
|
2
|
+
== Version 1.1.0 2010-07-28
|
3
|
+
|
4
|
+
* Add a pure java extension so hitimes may be used in jruby with the same API
|
5
|
+
|
6
|
+
== Version 1.0.5 2010-07-20
|
7
|
+
|
8
|
+
* Fix 'circular require considered harmful' warnings in 1.9.x (reported by Roger Pack)
|
9
|
+
* Fix 'method redefined' warnings in 1.9.x (reported by Roger Pack)
|
10
|
+
|
11
|
+
== Version 1.0.4 2009-08-01
|
12
|
+
|
13
|
+
* Add in support for x86-mingw32 gem
|
14
|
+
* Add version subdirectory for extension on all platforms
|
15
|
+
|
16
|
+
== Version 1.0.3 2009-06-28
|
17
|
+
|
18
|
+
* Fix bug with time.h on linode (reported by Roger Pack)
|
19
|
+
* Fix potential garbage collection issue with Interval class
|
20
|
+
* Windows gem is now a fat binary to support installing in 1.8 or 1.9 from the
|
21
|
+
same gem
|
22
|
+
|
23
|
+
== Version 1.0.1 2009-06-12
|
24
|
+
|
25
|
+
* Fix examples
|
26
|
+
* performance tuning, new Hitimes::Metric derived classes are faster than old Timer class
|
27
|
+
|
28
|
+
== Version 1.0.0 2009-06-12
|
29
|
+
|
30
|
+
* Major version bump with complete refactor of the metric collection API
|
31
|
+
* 3 types of metrics now instead of just 1 Timer
|
32
|
+
* Hitimes::ValueMetric
|
33
|
+
* Hitimes::TimedMetric
|
34
|
+
* Hitimes::TimedValueMetric
|
35
|
+
* The ability to convert all metrics #to_hash
|
36
|
+
* Updated documentation with examples using each metric type
|
37
|
+
|
38
|
+
== Version 0.4.1 2009-02-19
|
39
|
+
|
40
|
+
* change to ISC License
|
41
|
+
* fix bug in compilation on gentoo
|
42
|
+
|
43
|
+
== Version 0.4.0 2008-12-20
|
44
|
+
|
45
|
+
* Added new stat 'rate'
|
46
|
+
* Added new stat method to_hash
|
47
|
+
* Added Hitimes::MutexedStats class for threadsafe stats collection
|
48
|
+
- not needed when used in MRI 1.8.x
|
49
|
+
* remove stale dependency on mkrf
|
50
|
+
|
51
|
+
== Version 0.3.0
|
52
|
+
|
53
|
+
* switched to extconf for building extensions
|
54
|
+
* first release of windows binary gem
|
55
|
+
* reverted back to normal rdoc
|
56
|
+
|
57
|
+
== Version 0.2.1
|
58
|
+
|
59
|
+
* added Timer#rate method
|
60
|
+
* switched to darkfish rdoc
|
61
|
+
|
62
|
+
== Version 0.2.0
|
63
|
+
|
64
|
+
* Performance improvements
|
65
|
+
* Added Hitimes::Stats class
|
66
|
+
|
67
|
+
== Version 0.1.0
|
68
|
+
|
69
|
+
* Initial completion
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2008 Jeremy Hinegardner
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
11
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
12
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
13
|
+
PERFORMANCE OF THIS SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
== hitimes
|
2
|
+
|
3
|
+
* Homepage[http://copiousfreetime.rubyforge.org/hitimes]
|
4
|
+
* {Rubyforge project}[http://rubyforge.org/projects/copiousfreetime/]
|
5
|
+
* email jeremy at copiousfreetime dot org
|
6
|
+
* git clone url git://github.com/copiousfreetime/hitimes.git
|
7
|
+
|
8
|
+
== INSTALL
|
9
|
+
|
10
|
+
* gem install hitimes
|
11
|
+
|
12
|
+
== DESCRIPTION
|
13
|
+
|
14
|
+
Hitimes is a fast, high resolution timer library for recording
|
15
|
+
performance metrics. It uses the appropriate C method calls for each
|
16
|
+
system to get the highest granularity time increments possible.
|
17
|
+
|
18
|
+
It currently supports any of the following systems:
|
19
|
+
|
20
|
+
* any system with the POSIX call <tt>clock_gettime()</tt>,
|
21
|
+
* Mac OS X
|
22
|
+
* Windows
|
23
|
+
|
24
|
+
Using Hitimes can be faster than using a series of +Time.new+ calls, and
|
25
|
+
it will have a much higher granularity. It is definitely faster than
|
26
|
+
using +Process.times+.
|
27
|
+
|
28
|
+
== SYNOPSIS
|
29
|
+
|
30
|
+
=== Interval
|
31
|
+
|
32
|
+
Use Hitimes::Interval to calculate only the duration of a block of code
|
33
|
+
|
34
|
+
duration = Hitimes::Interval.measure do
|
35
|
+
# some operation ...
|
36
|
+
end
|
37
|
+
|
38
|
+
puts duration
|
39
|
+
|
40
|
+
=== TimedMetric
|
41
|
+
|
42
|
+
Use a Hitimes::TimedMetric to calculate statistics about an iterative operation
|
43
|
+
|
44
|
+
timed_metric = Hitimes::TimedMetric.new('operation on items')
|
45
|
+
|
46
|
+
Explicitly use +start+ and +stop+:
|
47
|
+
|
48
|
+
collection.each do |item|
|
49
|
+
timed_metric.start
|
50
|
+
# .. do something with item
|
51
|
+
timed_metric.stop
|
52
|
+
end
|
53
|
+
|
54
|
+
Or use the block. In TimedMetric the return value of +measure+ is the return
|
55
|
+
value of the block
|
56
|
+
|
57
|
+
collection.each do |item|
|
58
|
+
result_of_do_something = timed_metric.measure { do_something( item ) }
|
59
|
+
end
|
60
|
+
|
61
|
+
And then look at the stats
|
62
|
+
|
63
|
+
puts timed_metric.mean
|
64
|
+
puts timed_metric.max
|
65
|
+
puts timed_metric.min
|
66
|
+
puts timed_metric.stddev
|
67
|
+
puts timed_metric.rate
|
68
|
+
|
69
|
+
=== ValueMetric
|
70
|
+
|
71
|
+
Use a Hitimes::ValueMetric to calculate statistics about measured samples
|
72
|
+
|
73
|
+
value_metric = Hitimes::ValueMetric.new( 'size of thing' )
|
74
|
+
loop do
|
75
|
+
# ... do stuff changing sizes of 'thing'
|
76
|
+
value_metric.measure( thing.size )
|
77
|
+
# ... do other stuff that may change size of thing
|
78
|
+
end
|
79
|
+
|
80
|
+
puts value_metric.mean
|
81
|
+
puts value_metric.max
|
82
|
+
puts value_metric.min
|
83
|
+
puts value_metric.stddev
|
84
|
+
puts value_metric.rate
|
85
|
+
|
86
|
+
|
87
|
+
=== TimedValueMetric
|
88
|
+
|
89
|
+
Use a Hitimes::TimedValueMetric to calculate statistics about batches of samples
|
90
|
+
|
91
|
+
timed_value_metric = Hitimes::TimedValueMetric.new( 'batch times' )
|
92
|
+
loop do
|
93
|
+
batch = ... # get a batch of things
|
94
|
+
timed_value_metric.start
|
95
|
+
# .. do something with batch
|
96
|
+
timed_value_metric.stop( batch.size )
|
97
|
+
end
|
98
|
+
|
99
|
+
puts timed_value_metric.rate
|
100
|
+
|
101
|
+
puts timed_value_metric.timed_stats.mean
|
102
|
+
puts timed_value_metric.timed_stats.max
|
103
|
+
puts timed_value_metric.timed_stats.min
|
104
|
+
puts timed_value_metric.timed_stats.stddev
|
105
|
+
|
106
|
+
puts timed_value_metric.value_stats.mean
|
107
|
+
puts timed_value_metric.value_stats.max
|
108
|
+
puts timed_value_metric.value_stats.min
|
109
|
+
puts timed_value_metric.value_stats.stddev
|
110
|
+
|
111
|
+
|
112
|
+
== CHANGES
|
113
|
+
|
114
|
+
Read the HISTORY file.
|
115
|
+
|
116
|
+
== CREDITS
|
117
|
+
|
118
|
+
* Bruce Williams for suggesting the idea
|
119
|
+
|
120
|
+
== ISC License
|
121
|
+
|
122
|
+
Copyright (c) 2008 Jeremy Hinegardner
|
123
|
+
|
124
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
125
|
+
purpose with or without fee is hereby granted, provided that the above
|
126
|
+
copyright notice and this permission notice appear in all copies.
|
127
|
+
|
128
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
129
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
130
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
131
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
132
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
133
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
134
|
+
PERFORMANCE OF THIS SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Jeremy Hinegardner
|
3
|
+
# All rights reserved. See LICENSE and/or COPYING for details.
|
4
|
+
#++
|
5
|
+
|
6
|
+
#-------------------------------------------------------------------------------
|
7
|
+
# make sure our project's top level directory and the lib directory are added to
|
8
|
+
# the ruby search path.
|
9
|
+
#-------------------------------------------------------------------------------
|
10
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"ext"))
|
11
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"lib"))
|
12
|
+
$: << File.expand_path(File.dirname(__FILE__))
|
13
|
+
|
14
|
+
|
15
|
+
#-------------------------------------------------------------------------------
|
16
|
+
# load the global project configuration and add in the top level clean and
|
17
|
+
# clobber tasks so that other tasks can utilize those constants if necessary
|
18
|
+
# This loads up the defaults for the whole project configuration
|
19
|
+
#-------------------------------------------------------------------------------
|
20
|
+
require 'rubygems'
|
21
|
+
require 'tasks/config.rb'
|
22
|
+
require 'rake/clean'
|
23
|
+
|
24
|
+
#-------------------------------------------------------------------------------
|
25
|
+
# Main configuration for the project, these overwrite the items that are in
|
26
|
+
# tasks/config.rb
|
27
|
+
#-------------------------------------------------------------------------------
|
28
|
+
require 'hitimes/version'
|
29
|
+
require 'hitimes/paths'
|
30
|
+
|
31
|
+
Configuration.for("project") {
|
32
|
+
name "hitimes"
|
33
|
+
version Hitimes::VERSION
|
34
|
+
author "Jeremy Hinegardner"
|
35
|
+
email "jeremy@copiousfreetime.org"
|
36
|
+
homepage "http://copiousfreetime.rubyforge.org/hitimes/"
|
37
|
+
}
|
38
|
+
|
39
|
+
#-------------------------------------------------------------------------------
|
40
|
+
# load up all the project tasks and setup the default task to be the
|
41
|
+
# test:default task.
|
42
|
+
#-------------------------------------------------------------------------------
|
43
|
+
Configuration.for("packaging").files.tasks.each do |tasklib|
|
44
|
+
import tasklib
|
45
|
+
end
|
46
|
+
task :default => 'test:default'
|
47
|
+
|
48
|
+
#-------------------------------------------------------------------------------
|
49
|
+
# Finalize the loading of all pending imports and update the top level clobber
|
50
|
+
# task to depend on all possible sub-level tasks that have a name like
|
51
|
+
# ':clobber' in other namespaces. This allows us to say:
|
52
|
+
#
|
53
|
+
# rake clobber
|
54
|
+
#
|
55
|
+
# and it will get everything.
|
56
|
+
#-------------------------------------------------------------------------------
|
57
|
+
Rake.application.load_imports
|
58
|
+
Rake.application.tasks.each do |t|
|
59
|
+
if t.name =~ /:clobber/ then
|
60
|
+
task :clobber => [t.name]
|
61
|
+
end
|
62
|
+
if t.name =~ /:clean/ then
|
63
|
+
task :clean => [t.name]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
#
|
5
|
+
# this is all here in case this example is run from the examples directory
|
6
|
+
#
|
7
|
+
begin
|
8
|
+
require 'hitimes'
|
9
|
+
rescue LoadError => le
|
10
|
+
ext_path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", "ext" ) )
|
11
|
+
lib_path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", "lib" ) )
|
12
|
+
if $:.include?( ext_path ) then
|
13
|
+
raise le
|
14
|
+
end
|
15
|
+
$: << ext_path
|
16
|
+
$: << lib_path
|
17
|
+
retry
|
18
|
+
end
|
19
|
+
|
20
|
+
#----------------------------------------------------------------------
|
21
|
+
# test program to look at the performance sampling time durations using
|
22
|
+
# different methods
|
23
|
+
#----------------------------------------------------------------------
|
24
|
+
|
25
|
+
include Benchmark
|
26
|
+
|
27
|
+
#
|
28
|
+
# Normal apprach to Interval usage
|
29
|
+
#
|
30
|
+
def hitimes_duration_i1
|
31
|
+
i = Hitimes::Interval.new
|
32
|
+
i.start
|
33
|
+
i.stop
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Use the easy access method to start stop an interval
|
38
|
+
#
|
39
|
+
def hitimes_duration_i2
|
40
|
+
Hitimes::Interval.now.stop
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Use a new timer each time
|
45
|
+
#
|
46
|
+
def hitimes_duration_t1
|
47
|
+
Hitimes::TimedMetric.now('duration_t1').stop
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# reuse the same timer over and over
|
52
|
+
#
|
53
|
+
HT2= Hitimes::TimedMetric.new( 'duration_t2' )
|
54
|
+
def hitimes_duration_t2
|
55
|
+
HT2.start
|
56
|
+
HT2.stop
|
57
|
+
end
|
58
|
+
|
59
|
+
HT3 = Hitimes::TimedMetric.new( 'duration_t3' )
|
60
|
+
def hitimes_duration_t3
|
61
|
+
HT3.measure { nil }
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Check out the speed of the TimedValueMetric too
|
66
|
+
#
|
67
|
+
def hitimes_duration_tv1
|
68
|
+
Hitimes::TimedValueMetric.now( 'duration_tv1' ).stop( 42 )
|
69
|
+
end
|
70
|
+
|
71
|
+
HTV2 = Hitimes::TimedValueMetric.new( 'duration_tv2' )
|
72
|
+
def hitimes_duration_tv2
|
73
|
+
HTV2.start
|
74
|
+
HTV2.stop( 42 )
|
75
|
+
end
|
76
|
+
|
77
|
+
HTV3 = Hitimes::TimedValueMetric.new( 'duration_tv3' )
|
78
|
+
def hitimes_duration_tv3
|
79
|
+
HTV3.measure( 42 ) { nil }
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# use the Struct::Tms values and return the difference in User time between 2
|
84
|
+
# successive calls
|
85
|
+
#
|
86
|
+
def process_duration
|
87
|
+
t1 = Process.times.utime
|
88
|
+
Process.times.utime - t1
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Take 2 times and subtract one from the other
|
93
|
+
#
|
94
|
+
def time_duration
|
95
|
+
t1 = Time.now.to_f
|
96
|
+
Time.now.to_f - t1
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
puts "Testing time sampling 100,000 times"
|
101
|
+
|
102
|
+
bm(30) do |x|
|
103
|
+
x.report("Process") { 100_000.times { process_duration } }
|
104
|
+
x.report("Time") { 100_000.times { time_duration } }
|
105
|
+
x.report("Hitimes::TimedMetric 1") { 100_000.times { hitimes_duration_t1 } }
|
106
|
+
x.report("Hitimes::TimedMetric 2") { 100_000.times { hitimes_duration_t2 } }
|
107
|
+
x.report("Hitimes::TimedMetric 3") { 100_000.times { hitimes_duration_t3 } }
|
108
|
+
x.report("Hitimes::Interval 1") { 100_000.times { hitimes_duration_i1 } }
|
109
|
+
x.report("Hitimes::Interval 2") { 100_000.times { hitimes_duration_i2 } }
|
110
|
+
x.report("Hitimes::TimedValueMetric 1") { 100_000.times { hitimes_duration_tv1 } }
|
111
|
+
x.report("Hitimes::TimedValueMetric 2") { 100_000.times { hitimes_duration_tv2 } }
|
112
|
+
x.report("Hitimes::TimedValueMetric 3") { 100_000.times { hitimes_duration_tv3 } }
|
113
|
+
end
|
data/examples/stats.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# this is all here in case this example is run from the examples directory
|
3
|
+
#
|
4
|
+
begin
|
5
|
+
require 'hitimes'
|
6
|
+
rescue LoadError => le
|
7
|
+
%w[ ext lib ].each do |p|
|
8
|
+
path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", p ) )
|
9
|
+
if $:.include?( path ) then
|
10
|
+
raise le
|
11
|
+
end
|
12
|
+
$: << path
|
13
|
+
end
|
14
|
+
retry
|
15
|
+
end
|
16
|
+
|
17
|
+
s = Hitimes::Stats.new
|
18
|
+
dir = ARGV.shift || Dir.pwd
|
19
|
+
Dir.entries( dir ).each do |entry|
|
20
|
+
fs = File.stat( entry )
|
21
|
+
if fs.file? then
|
22
|
+
s.update( fs.size )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Hitimes::Stats::STATS.each do |m|
|
27
|
+
puts "#{m.rjust(6)} : #{s.send( m ) }"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts s.to_hash.inspect
|
31
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
if Config::CONFIG['host_os'] =~ /darwin/ then
|
5
|
+
$CFLAGS += " -DUSE_INSTANT_OSX=1 -Wall"
|
6
|
+
$LDFLAGS += " -framework CoreServices"
|
7
|
+
elsif Config::CONFIG['host_os'] =~ /win32/ or Config::CONFIG['host_os'] =~ /mingw/ then
|
8
|
+
$CFLAGS += " -DUSE_INSTANT_WINDOWS=1"
|
9
|
+
else
|
10
|
+
if have_library("rt", "clock_gettime") then
|
11
|
+
$CFLAGS += " -DUSE_INSTANT_CLOCK_GETTIME=1"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# put in a different location if on windows so we can have fat binaries
|
16
|
+
subdir = RUBY_VERSION.gsub(/\.\d$/,'')
|
17
|
+
create_makefile("hitimes/#{subdir}/hitimes_ext")
|