hitimes 1.0.4-x86-mingw32

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.
Files changed (46) hide show
  1. data/HISTORY +60 -0
  2. data/LICENSE +13 -0
  3. data/README +134 -0
  4. data/Rakefile +66 -0
  5. data/examples/benchmarks.rb +113 -0
  6. data/examples/stats.rb +31 -0
  7. data/ext/hitimes/extconf.rb +17 -0
  8. data/ext/hitimes/hitimes_ext.c +21 -0
  9. data/ext/hitimes/hitimes_instant_clock_gettime.c +28 -0
  10. data/ext/hitimes/hitimes_instant_osx.c +16 -0
  11. data/ext/hitimes/hitimes_instant_windows.c +27 -0
  12. data/ext/hitimes/hitimes_interval.c +362 -0
  13. data/ext/hitimes/hitimes_interval.h +73 -0
  14. data/ext/hitimes/hitimes_stats.c +269 -0
  15. data/ext/hitimes/hitimes_stats.h +30 -0
  16. data/gemspec.rb +60 -0
  17. data/lib/hitimes.rb +31 -0
  18. data/lib/hitimes/1.8/hitimes_ext.so +0 -0
  19. data/lib/hitimes/1.9/hitimes_ext.so +0 -0
  20. data/lib/hitimes/metric.rb +112 -0
  21. data/lib/hitimes/mutexed_stats.rb +28 -0
  22. data/lib/hitimes/paths.rb +53 -0
  23. data/lib/hitimes/stats.rb +54 -0
  24. data/lib/hitimes/timed_metric.rb +177 -0
  25. data/lib/hitimes/timed_value_metric.rb +235 -0
  26. data/lib/hitimes/value_metric.rb +72 -0
  27. data/lib/hitimes/version.rb +57 -0
  28. data/spec/interval_spec.rb +133 -0
  29. data/spec/metric_spec.rb +30 -0
  30. data/spec/mutex_stats_spec.rb +34 -0
  31. data/spec/paths_spec.rb +13 -0
  32. data/spec/spec_helper.rb +5 -0
  33. data/spec/stats_spec.rb +100 -0
  34. data/spec/timed_metric_spec.rb +155 -0
  35. data/spec/timed_value_metric_spec.rb +172 -0
  36. data/spec/value_metric_spec.rb +110 -0
  37. data/spec/version_spec.rb +33 -0
  38. data/tasks/announce.rake +42 -0
  39. data/tasks/config.rb +108 -0
  40. data/tasks/distribution.rake +77 -0
  41. data/tasks/documentation.rake +32 -0
  42. data/tasks/extension.rake +92 -0
  43. data/tasks/rspec.rake +31 -0
  44. data/tasks/rubyforge.rake +55 -0
  45. data/tasks/utils.rb +80 -0
  46. metadata +150 -0
data/HISTORY ADDED
@@ -0,0 +1,60 @@
1
+ = Changelog
2
+ == Version 1.0.4 2009-08-1
3
+
4
+ * Add in support for x86-mingw32 gem
5
+ * Add version subdirectory for extension on all platforms
6
+
7
+ == Version 1.0.3 2009-06-28
8
+
9
+ * Fix bug with time.h on linode (reported by Roger Pack)
10
+ * Fix potential garbage collection issue with Interval class
11
+ * Windows gem is now a fat binary to support installing in 1.8 or 1.9 from the
12
+ same gem
13
+
14
+ == Version 1.0.1 2009-06-12
15
+
16
+ * Fix examples
17
+ * performance tuning, new Hitimes::Metric derived classes are faster than old Timer class
18
+
19
+ == Version 1.0.0 2009-06-12
20
+
21
+ * Major version bump with complete refactor of the metric collection API
22
+ * 3 types of metrics now instead of just 1 Timer
23
+ * Hitimes::ValueMetric
24
+ * Hitimes::TimedMetric
25
+ * Hitimes::TimedValueMetric
26
+ * The ability to convert all metrics #to_hash
27
+ * Updated documentation with examples using each metric type
28
+
29
+ == Version 0.4.1 2009-02-19
30
+
31
+ * change to ISC License
32
+ * fix bug in compilation on gentoo
33
+
34
+ == Version 0.4.0 2008-12-20
35
+
36
+ * Added new stat 'rate'
37
+ * Added new stat method to_hash
38
+ * Added Hitimes::MutexedStats class for threadsafe stats collection
39
+ - not needed when used in MRI 1.8.x
40
+ * remove stale dependency on mkrf
41
+
42
+ == Version 0.3.0
43
+
44
+ * switched to extconf for building extensions
45
+ * first release of windows binary gem
46
+ * reverted back to normal rdoc
47
+
48
+ == Version 0.2.1
49
+
50
+ * added Timer#rate method
51
+ * switched to darkfish rdoc
52
+
53
+ == Version 0.2.0
54
+
55
+ * Performance improvements
56
+ * Added Hitimes::Stats class
57
+
58
+ == Version 0.1.0
59
+
60
+ * 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")
@@ -0,0 +1,21 @@
1
+ #include <ruby.h>
2
+ #include "hitimes_interval.h"
3
+
4
+ /* Module and Classes */
5
+ VALUE mH; /* module Hitimes */
6
+ VALUE eH_Error; /* class Hitimes::Error */
7
+
8
+ /*
9
+ * Document-class: Hitimes::Error
10
+ *
11
+ * General error class for the Hitimes module
12
+ */
13
+ void Init_hitimes_ext( )
14
+ {
15
+ mH = rb_define_module("Hitimes");
16
+
17
+ eH_Error = rb_define_class_under(mH, "Error", rb_eStandardError);
18
+
19
+ Init_hitimes_interval();
20
+ Init_hitimes_stats( );
21
+ }