hitimes 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,73 +0,0 @@
1
- /**
2
- * Copyright (c) 2008 Jeremy Hinegardner
3
- * All rights reserved. See LICENSE and/or COPYING for details.
4
- *
5
- * vim: shiftwidth=4
6
- */
7
-
8
- #ifndef __HITIMES_INTERVAL_H__
9
- #define __HITIMES_INTERVAL_H__
10
-
11
- #include <ruby.h>
12
-
13
- #define NANOSECONDS_PER_SECOND 1e9l
14
-
15
- #ifdef USE_INSTANT_CLOCK_GETTIME
16
- # define HITIMES_U64INT unsigned long long int
17
- # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9l
18
- #elif USE_INSTANT_OSX
19
- # define HITIMES_U64INT uint64_t
20
- # define HITIMES_INSTANT_CONVERSION_FACTOR hitimes_instant_conversion_factor()
21
- #elif USE_INSTANT_WINDOWS
22
- # define HITIMES_U64INT unsigned __int64
23
- # define HITIMES_INSTANT_CONVERSION_FACTOR hitimes_instant_conversion_factor()
24
- #else
25
- # error "Unable to build hitimes, no Instance backend available"
26
- #endif
27
-
28
-
29
- /* an alias for a 64bit unsigned integer. The various sytem dependenent
30
- * files must define hitimes_u64int_t
31
- */
32
- typedef HITIMES_U64INT hitimes_instant_t;
33
-
34
- typedef struct hitimes_interval {
35
- hitimes_instant_t start_instant;
36
- hitimes_instant_t stop_instant;
37
- long double duration;
38
- } hitimes_interval_t;
39
-
40
- /* all the backends must define these methods */
41
- hitimes_instant_t hitimes_get_current_instant( );
42
- long double hitimes_instant_conversion_factor( );
43
-
44
- /* init methods */
45
- void Init_hitimes_stats();
46
- void Init_hitimes_interval();
47
-
48
-
49
- /* Module and Classes -- defined at the top level */
50
- extern VALUE mH; /* module Hitimes */
51
- extern VALUE eH_Error; /* class Hitimes::Error */
52
- extern VALUE cH_Interval; /* class Hitimes::Interval */
53
-
54
-
55
- /**
56
- * Methods for Interval
57
- */
58
-
59
- VALUE hitimes_interval_free(hitimes_interval_t* i) ;
60
- VALUE hitimes_interval_alloc(VALUE klass);
61
- VALUE hitimes_interval_now( );
62
- VALUE hitimes_interval_measure( );
63
- VALUE hitimes_interval_split( VALUE self );
64
- VALUE hitimes_interval_start( VALUE self );
65
- VALUE hitimes_interval_stop( VALUE self );
66
- VALUE hitimes_interval_started( VALUE self );
67
- VALUE hitimes_interval_stopped( VALUE self );
68
- VALUE hitimes_interval_running( VALUE self );
69
- VALUE hitimes_interval_start_instant( VALUE self );
70
- VALUE hitimes_interval_stop_instant( VALUE self );
71
- VALUE hitimes_interval_duration ( VALUE self );
72
-
73
- #endif
@@ -1,269 +0,0 @@
1
- /**
2
- * Copyright (c) 2008 Jeremy Hinegardner
3
- * All rights reserved. See LICENSE and/or COPYING for details.
4
- *
5
- * vim: shiftwidth=4
6
- */
7
-
8
- #include "hitimes_stats.h"
9
-
10
- /* classes defined here */
11
- VALUE cH_Stats; /* Hitimes::Stats */
12
-
13
- /**
14
- * Allocator and Deallocator for Stats classes
15
- */
16
-
17
- VALUE hitimes_stats_free(hitimes_stats_t* s)
18
- {
19
- xfree( s );
20
- return Qnil;
21
- }
22
-
23
- VALUE hitimes_stats_alloc(VALUE klass)
24
- {
25
- VALUE obj;
26
- hitimes_stats_t* s = xmalloc( sizeof( hitimes_stats_t ) );
27
-
28
- s->min = 0.0;
29
- s->max = 0.0;
30
- s->count = 0;
31
- s->sum = 0.0;
32
- s->sumsq = 0.0;
33
-
34
- obj = Data_Wrap_Struct(klass, NULL, hitimes_stats_free, s);
35
-
36
- return obj;
37
- }
38
-
39
-
40
- /**
41
- * call-seq:
42
- * stat.update( val ) -> val
43
- *
44
- * Update the running stats with the new value.
45
- * Return the input value.
46
- */
47
- VALUE hitimes_stats_update( VALUE self, VALUE v )
48
- {
49
- long double new_v;
50
- hitimes_stats_t *stats;
51
-
52
- Data_Get_Struct( self, hitimes_stats_t, stats );
53
- new_v = NUM2DBL( v );
54
-
55
- if ( 0 == stats->count ) {
56
- stats->min = new_v;
57
- stats->max = new_v;
58
- } else {
59
- stats->min = ( new_v < stats->min) ? ( new_v ) : ( stats->min );
60
- stats->max = ( new_v > stats->max) ? ( new_v ) : ( stats->max );
61
- }
62
-
63
- stats->count += 1;
64
- stats->sum += new_v;
65
- stats->sumsq += ( new_v * new_v );
66
-
67
- return v;
68
- }
69
-
70
- /**
71
- * call-seq:
72
- * stat.mean -> Float
73
- *
74
- * Return the arithmetic mean of the values put into the Stats object. If no
75
- * values have passed through the stats object then 0.0 is returned;
76
- */
77
- VALUE hitimes_stats_mean( VALUE self )
78
- {
79
- hitimes_stats_t *stats;
80
- long double mean = 0.0;
81
-
82
- Data_Get_Struct( self, hitimes_stats_t, stats );
83
-
84
- if ( stats->count > 0 ) {
85
- mean = stats->sum / stats->count ;
86
- }
87
-
88
- return rb_float_new( mean );
89
- }
90
-
91
-
92
- /**
93
- * call-seq:
94
- * stat.rate -> Float
95
- *
96
- * Return the +count+ divided by +sum+.
97
- *
98
- * In many cases when Stats#update( _value_ ) is called, the _value_ is a unit
99
- * of time, typically seconds or microseconds. #rate is a convenience for those
100
- * times. In this case, where _value_ is a unit if time, then count divided by
101
- * sum is a useful value, i.e. +something per unit of time+.
102
- *
103
- * In the case where _value_ is a non-time related value, then the value
104
- * returned by _rate_ is not really useful.
105
- *
106
- */
107
- VALUE hitimes_stats_rate( VALUE self )
108
- {
109
- hitimes_stats_t *stats;
110
- long double rate = 0.0;
111
-
112
- Data_Get_Struct( self, hitimes_stats_t, stats );
113
-
114
- if ( stats->sum > 0.0 ) {
115
- rate = stats->count / stats->sum;
116
- }
117
-
118
- return rb_float_new( rate );
119
- }
120
-
121
-
122
- /**
123
- * call-seq:
124
- * stat.max -> Float
125
- *
126
- * Return the maximum value that has passed through the Stats object
127
- */
128
- VALUE hitimes_stats_max( VALUE self )
129
- {
130
- hitimes_stats_t *stats;
131
-
132
- Data_Get_Struct( self, hitimes_stats_t, stats );
133
-
134
- return rb_float_new( stats->max );
135
- }
136
-
137
-
138
-
139
- /**
140
- * call-seq:
141
- * stat.min -> Float
142
- *
143
- * Return the minimum value that has passed through the Stats object
144
- */
145
- VALUE hitimes_stats_min( VALUE self )
146
- {
147
- hitimes_stats_t *stats;
148
-
149
- Data_Get_Struct( self, hitimes_stats_t, stats );
150
-
151
- return rb_float_new( stats->min );
152
- }
153
-
154
-
155
- /**
156
- * call-seq:
157
- * stat.count -> Integer
158
- *
159
- * Return the number of values that have passed through the Stats object.
160
- */
161
- VALUE hitimes_stats_count( VALUE self )
162
- {
163
- hitimes_stats_t *stats;
164
-
165
- Data_Get_Struct( self, hitimes_stats_t, stats );
166
-
167
- return LONG2NUM( stats->count );
168
- }
169
-
170
-
171
- /**
172
- * call-seq:
173
- * stat.sum -> Float
174
- *
175
- * Return the sum of all the values that have passed through the Stats object.
176
- */
177
- VALUE hitimes_stats_sum( VALUE self )
178
- {
179
- hitimes_stats_t *stats;
180
-
181
- Data_Get_Struct( self, hitimes_stats_t, stats );
182
-
183
- return rb_float_new( stats->sum );
184
- }
185
-
186
- /**
187
- * call-seq:
188
- * stat.sumsq -> Float
189
- *
190
- * Return the sum of the squars of all the values that passed through the Stats
191
- * object.
192
- */
193
- VALUE hitimes_stats_sumsq( VALUE self )
194
- {
195
- hitimes_stats_t *stats;
196
-
197
- Data_Get_Struct( self, hitimes_stats_t, stats );
198
-
199
- return rb_float_new( stats->sumsq );
200
- }
201
-
202
-
203
- /**
204
- * call-seq:
205
- * stat.stddev -> Float
206
- *
207
- * Return the standard deviation of all the values that have passed through the
208
- * Stats object. The standard deviation has no meaning unless the count is > 1,
209
- * therefore if the current _stat.count_ is < 1 then 0.0 will be returned;
210
- */
211
- VALUE hitimes_stats_stddev ( VALUE self )
212
- {
213
- hitimes_stats_t *stats;
214
- long double stddev = 0.0;
215
-
216
- Data_Get_Struct( self, hitimes_stats_t, stats );
217
- if ( stats->count > 1 ) {
218
- stddev = sqrt( ( stats->sumsq - ( stats->sum * stats->sum / stats->count ) ) / ( stats->count - 1 ) );
219
- }
220
-
221
- return rb_float_new( stddev );
222
- }
223
-
224
-
225
- /**
226
- * Document-class: Hitimes::Stats
227
- *
228
- * The Stats class encapulsates capturing and reporting statistics. It is
229
- * modeled after the RFuzz::Sampler class, but implemented in C. For general use
230
- * you allocate a new Stats object, and then update it with new values. The
231
- * Stats object will keep track of the _min_, _max_, _count_, _sum_ and _sumsq_
232
- * and when you want you may also retrieve the _mean_, _stddev_ and _rate_.
233
- *
234
- * this contrived example shows getting a list of all the files in a directory
235
- * and running stats on file sizes.
236
- *
237
- * s = Hitimes::Stats.new
238
- * dir = ARGV.shift || Dir.pwd
239
- * Dir.entries( dir ).each do |entry|
240
- * fs = File.stat( entry )
241
- * if fs.file? then
242
- * s.update( fs.size )
243
- * end
244
- * end
245
- *
246
- * %w[ count min max mean sum stddev rate ].each do |m|
247
- * puts "#{m.rjust(6)} : #{s.send( m ) }"
248
- * end
249
- */
250
- void Init_hitimes_stats()
251
- {
252
-
253
- mH = rb_define_module("Hitimes");
254
-
255
- cH_Stats = rb_define_class_under( mH, "Stats", rb_cObject ); /* in hitimes_stats.c */
256
- rb_define_alloc_func( cH_Stats, hitimes_stats_alloc );
257
-
258
- rb_define_method( cH_Stats, "update", hitimes_stats_update, 1 ); /* in hitimes_stats.c */
259
-
260
- rb_define_method( cH_Stats, "count", hitimes_stats_count, 0 ); /* in hitimes_stats.c */
261
- rb_define_method( cH_Stats, "max", hitimes_stats_max, 0 ); /* in hitimes_stats.c */
262
- rb_define_method( cH_Stats, "mean", hitimes_stats_mean, 0 ); /* in hitimes_stats.c */
263
- rb_define_method( cH_Stats, "min", hitimes_stats_min, 0 ); /* in hitimes_stats.c */
264
- rb_define_method( cH_Stats, "rate", hitimes_stats_rate, 0 ); /* in hitimes_stats.c */
265
- rb_define_method( cH_Stats, "sum", hitimes_stats_sum, 0 ); /* in hitimes_stats.c */
266
- rb_define_method( cH_Stats, "sumsq", hitimes_stats_sumsq, 0 ); /* in hitimes_stats.c */
267
- rb_define_method( cH_Stats, "stddev", hitimes_stats_stddev, 0 ); /* in hitimes_stats.c */
268
- }
269
-
@@ -1,30 +0,0 @@
1
- /**
2
- * Copyright (c) 2008 Jeremy Hinegardner
3
- * All rights reserved. See LICENSE and/or COPYING for details.
4
- *
5
- * vim: shiftwidth=4
6
- */
7
-
8
- #ifndef __HITIMES_STATS_H__
9
- #define __HITIMES_STATS_H__
10
-
11
- #include <ruby.h>
12
- #include <math.h>
13
-
14
- /* classes and modules defined elswhere */
15
- extern VALUE mH; /* Hitimes */
16
- extern VALUE eH_Error; /* Hitimes::Error */
17
- extern VALUE cH_Stats; /* Hitimes::Stats */
18
-
19
-
20
- typedef struct hitimes_stats {
21
- long double min;
22
- long double max;
23
- long double sum;
24
- long double sumsq;
25
- long long count;
26
- } hitimes_stats_t;
27
-
28
- #endif
29
-
30
-
@@ -1,63 +0,0 @@
1
- package hitimes;
2
-
3
- import java.lang.Math;
4
- import java.lang.System;
5
-
6
- import org.jruby.Ruby;
7
- import org.jruby.RubyClass;
8
- import org.jruby.RubyException;
9
- import org.jruby.RubyModule;
10
- import org.jruby.RubyObject;
11
- import org.jruby.anno.JRubyClass;
12
- import org.jruby.anno.JRubyMethod;
13
- import org.jruby.anno.JRubyModule;
14
- import org.jruby.anno.JRubyConstant;
15
- import org.jruby.exceptions.RaiseException;
16
- import org.jruby.runtime.ThreadContext;
17
- import org.jruby.runtime.Visibility;
18
- import org.jruby.runtime.builtin.IRubyObject;
19
-
20
-
21
- /**
22
- * @author <a href="mailto:jeremy@hinegardner.org">Jeremy Hinegardner</a>
23
- */
24
- @JRubyModule( name = "Hitimes" )
25
- public class Hitimes {
26
-
27
- public static final double INSTANT_CONVERSION_FACTOR = 1000000000d;
28
-
29
- public static RubyClass hitimesIntervalClass;
30
-
31
- /**
32
- * Create the Hitimes module and add it to the Ruby runtime.
33
- */
34
- public static RubyModule createHitimesModule( Ruby runtime ) {
35
- RubyModule mHitimes = runtime.defineModule("Hitimes");
36
- mHitimes.defineConstant("INSTANT_CONVERSION_FACTOR", runtime.newFloat(INSTANT_CONVERSION_FACTOR));
37
- mHitimes.defineAnnotatedMethods( Hitimes.class );
38
-
39
- RubyClass cStandardError = runtime.getStandardError();
40
- RubyClass cHitimesError = mHitimes.defineClassUnder("Error", cStandardError, cStandardError.getAllocator());
41
-
42
- RubyClass cHitimesStats = mHitimes.defineClassUnder("Stats", runtime.getObject(), HitimesStats.ALLOCATOR );
43
- cHitimesStats.defineAnnotatedMethods( HitimesStats.class );
44
-
45
- RubyClass cHitimesInterval = mHitimes.defineClassUnder("Interval", runtime.getObject(), HitimesInterval.ALLOCATOR );
46
- Hitimes.hitimesIntervalClass = cHitimesInterval;
47
- cHitimesInterval.defineAnnotatedMethods( HitimesInterval.class );
48
-
49
- return mHitimes;
50
- }
51
-
52
- static RaiseException newHitimesError( Ruby runtime, String message ) {
53
- RubyClass errorClass = runtime.getModule("Hitimes").getClass( "Error" );
54
- return new RaiseException( RubyException.newException( runtime, errorClass, message ), true );
55
- }
56
-
57
-
58
- @JRubyMethod( name = "raw_instant", module = true )
59
- public static IRubyObject rawInstant(ThreadContext context, IRubyObject self) {
60
- return context.runtime.newFixnum( System.nanoTime() );
61
- }
62
-
63
- }
@@ -1,176 +0,0 @@
1
- package hitimes;
2
-
3
- import org.jruby.runtime.builtin.IRubyObject;
4
-
5
- import org.jruby.Ruby;
6
- import org.jruby.RubyClass;
7
- import org.jruby.RubyObject;
8
-
9
- import org.jruby.runtime.Block;
10
- import org.jruby.runtime.ObjectAllocator;
11
- import org.jruby.runtime.ThreadContext;
12
-
13
- import org.jruby.anno.JRubyClass;
14
- import org.jruby.anno.JRubyMethod;
15
-
16
- @JRubyClass( name = "Hitimes::Interval" )
17
- public class HitimesInterval extends RubyObject {
18
-
19
- private static final long INSTANT_NOT_SET = Long.MIN_VALUE;
20
- private static final double DURATION_NOT_SET = Double.NaN;
21
-
22
- public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
23
- public IRubyObject allocate(Ruby runtime, RubyClass klass) {
24
- return new HitimesInterval( runtime, klass );
25
- }
26
- };
27
-
28
- public HitimesInterval( Ruby runtime, RubyClass klass ) {
29
- super( runtime, klass );
30
- }
31
-
32
- public HitimesInterval( Ruby runtime, RubyClass klass, long start ) {
33
- super( runtime, klass );
34
- this.start_instant = start;
35
- }
36
-
37
-
38
- private long start_instant = INSTANT_NOT_SET;
39
- private long stop_instant = INSTANT_NOT_SET;
40
- private double duration = DURATION_NOT_SET;
41
-
42
- @JRubyMethod( name = "duration", alias = { "length", "to_f", "to_seconds" } )
43
- public IRubyObject duration() {
44
-
45
- /*
46
- * if start has not yet been called, then raise an exception.
47
- */
48
- if ( INSTANT_NOT_SET == this.start_instant ) {
49
- throw Hitimes.newHitimesError( getRuntime(), "Attempt to report a duration on an interval that has not started");
50
- }
51
-
52
- /*
53
- * if stop has not yet been called, then return the amount of time so far
54
- */
55
- if ( INSTANT_NOT_SET == this.stop_instant ) {
56
- double d = ( System.nanoTime() - this.start_instant ) / Hitimes.INSTANT_CONVERSION_FACTOR;
57
- return getRuntime().newFloat( d );
58
- }
59
-
60
- /*
61
- * if stop has been called, then calculate the duration and return
62
- */
63
- if ( DURATION_NOT_SET == this.duration ) {
64
- this.duration = (this.stop_instant - this.start_instant) / Hitimes.INSTANT_CONVERSION_FACTOR;
65
- }
66
-
67
- return getRuntime().newFloat( this.duration );
68
-
69
- }
70
-
71
- @JRubyMethod( name = "duration_so_far" )
72
- public IRubyObject duration_so_far() {
73
- IRubyObject rc = getRuntime().getFalse();
74
-
75
- if ( INSTANT_NOT_SET == this.start_instant ) {
76
- return rc;
77
- }
78
-
79
- if ( INSTANT_NOT_SET == this.stop_instant ) {
80
- double d = ( System.nanoTime() - this.start_instant ) / Hitimes.INSTANT_CONVERSION_FACTOR;
81
- return getRuntime().newFloat( d );
82
- }
83
-
84
- return rc;
85
- }
86
-
87
- @JRubyMethod( name = "started?" )
88
- public IRubyObject is_started() {
89
- if ( INSTANT_NOT_SET == this.start_instant ) {
90
- return getRuntime().getFalse();
91
- }
92
- return getRuntime().getTrue();
93
- }
94
-
95
- @JRubyMethod( name = "running?" )
96
- public IRubyObject is_running() {
97
- if ( ( INSTANT_NOT_SET != this.start_instant ) && ( INSTANT_NOT_SET == this.stop_instant ) ) {
98
- return getRuntime().getTrue();
99
- }
100
- return getRuntime().getFalse();
101
- }
102
-
103
- @JRubyMethod( name = "stopped?" )
104
- public IRubyObject is_stopped() {
105
- if ( INSTANT_NOT_SET == this.stop_instant ) {
106
- return getRuntime().getFalse();
107
- }
108
- return getRuntime().getTrue();
109
- }
110
-
111
- @JRubyMethod( name = "start_instant" )
112
- public IRubyObject start_instant() {
113
- return getRuntime().newFixnum( this.start_instant );
114
- }
115
-
116
- @JRubyMethod( name = "stop_instant" )
117
- public IRubyObject stop_instant() {
118
- return getRuntime().newFixnum( this.stop_instant );
119
- }
120
-
121
- @JRubyMethod( name = "start" )
122
- public IRubyObject start() {
123
- if ( INSTANT_NOT_SET == this.start_instant ) {
124
- this.start_instant = System.nanoTime();
125
- return getRuntime().getTrue();
126
- }
127
- return getRuntime().getFalse();
128
- }
129
-
130
- @JRubyMethod( name = "stop" )
131
- public IRubyObject stop() {
132
- if ( INSTANT_NOT_SET == this.start_instant ) {
133
- throw Hitimes.newHitimesError( getRuntime(), "Attempt to stop an interval that has not started" );
134
- }
135
-
136
- if ( INSTANT_NOT_SET == this.stop_instant ) {
137
- this.stop_instant = System.nanoTime();
138
- this.duration = (this.stop_instant - this.start_instant) / Hitimes.INSTANT_CONVERSION_FACTOR;
139
- return getRuntime().newFloat( this.duration );
140
- }
141
-
142
- return getRuntime().getFalse();
143
- }
144
-
145
- @JRubyMethod( name = "split" )
146
- public IRubyObject split() {
147
- this.stop();
148
- return new HitimesInterval( getRuntime(), Hitimes.hitimesIntervalClass, this.stop_instant );
149
- }
150
-
151
- @JRubyMethod( name = "now", module = true )
152
- public static IRubyObject now( IRubyObject self ) {
153
- return new HitimesInterval( self.getRuntime(), Hitimes.hitimesIntervalClass, System.nanoTime() );
154
- }
155
-
156
- @JRubyMethod( name = "measure", module = true, frame = true )
157
- public static IRubyObject measure( IRubyObject self, Block block ) {
158
-
159
- Ruby runtime = self.getRuntime();
160
-
161
- if ( block.isGiven() ) {
162
- IRubyObject nil = runtime.getNil();
163
- ThreadContext context = runtime.getCurrentContext();
164
-
165
- HitimesInterval interval = new HitimesInterval( runtime, Hitimes.hitimesIntervalClass );
166
-
167
- interval.start();
168
- block.yield( context, nil );
169
- interval.stop();
170
-
171
- return interval.duration();
172
- } else {
173
- throw Hitimes.newHitimesError( runtime, "No block given to Interval.measure" );
174
- }
175
- }
176
- }