-
Notifications
You must be signed in to change notification settings - Fork 0
/
Timer.rb
157 lines (126 loc) · 2.53 KB
/
Timer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class Timer
def self.now
Time.now
# Following in combination with controlled GC running generates
# segmentation faults!
#
# This proper timing creates timeouts, unfortunately
#Process.times.utime + Process.times.stime
end
def now
Timer.now
end
def initialize
@list = {}
# Following to make throttle calc on first turn work.
@list[ :yield ] = [ now, now, 0 ]
@count = 0
@max = {}
end
def start key
@list[ key ] = [ now, nil, @count ]
@count += 1
if block_given?
yield
self.end key
end
end
def add_max key, value
if @max[ key ].nil? or value > @max[ key ]
@max[ key ] = value
end
end
def end key
v = @list[ key]
if v
v[1] = now
value = ( (v[1] - v[0])*1000 ).to_i
add_max key, value
else
$logger.info { "No start time for #{ key } " }
end
end
def clear
# Don't delete yield
if @list[ :yield ]
val = @list[ :yield ]
val[2] = 0
@list = {}
@list[ :yield ] = val
@count = 1
else
@list = {}
@count = 0
end
end
#
# Return running value of timer in msec.
# If timer finished, return end value.
# If timer doesn't exist return null.
#
def value key
v = @list[ key ]
val = nil
if v
if v[1]
val = ( ( v[1] - v[0])*1000 ).to_i
else
val = ( ( now - v[0])*1000 ).to_i
end
end
val
end
def display
str = "Timer results (msec):\n";
start = now
max_k = nil
@list.each_pair do |k,v|
if max_k.nil? or max_k.length < k.length
max_k = k
end
end
lines = []
uncomplete = []
@list.each_pair do |k,v|
if v[1].nil?
uncomplete << [k, v]
next
end
value = ( (v[1] - v[0])*1000 ).to_i
lines << [
" %-#{ max_k.length }s %5d %5d" % [ k, value, @max[k] ],
v[2]
]
end
lines.sort! { |l1, l2| l1[1] <=> l2[1] }
str <<
" %-#{ max_k.length }s %5s %5s\n" % [ "Label", "Value", "Max" ] <<
" %-#{ max_k.length }s %5s %5s\n" % [ "=" * max_k.length , "=" * 5, "=" * 5 ] <<
lines.transpose[0].join( "\n" )
if uncomplete.length > 0
tmp = uncomplete.collect {|n|
value = ( (start - n[1][0])*1000 ).to_i
"#{ n[0] }: #{ value} msec"
}
str << "\nDid not complete:\n " + tmp.join( "\n ")
end
# After creating the stats, we can reset the faulty timers
# Except for yield, which is used for turn timing.
clear
str
end
def get key
v = @list[ key ]
unless v.nil?
endtime = v[1]
if endtime.nil?
$logger.info { "WARNING: timer #{ key } endtime nil!" }
nil
else
( (endtime - v[0])*1000).to_i
end
else
nil
end
end
end