Merge lp:~sidnei/txstatsd/faster-exponentially-decaying-sample into lp:txstatsd

Proposed by Sidnei da Silva
Status: Merged
Approved by: Sidnei da Silva
Approved revision: 90
Merged at revision: 88
Proposed branch: lp:~sidnei/txstatsd/faster-exponentially-decaying-sample
Merge into: lp:txstatsd
Diff against target: 113 lines (+26/-40)
1 file modified
txstatsd/stats/exponentiallydecayingsample.py (+26/-40)
To merge this branch: bzr merge lp:~sidnei/txstatsd/faster-exponentially-decaying-sample
Reviewer Review Type Date Requested Status
Lucio Torre (community) Approve
Review via email: mp+105438@code.launchpad.net

Commit message

Speed up update() by avoiding attribute access where possible

Description of the change

Speed up update() by avoiding attribute access where possible

To post a comment you must log in.
Revision history for this message
Lucio Torre (lucio.torre) wrote :

we can also remove the inner call to time.time() and use now = timestamp

review: Approve
90. By Sidnei da Silva

- Use timestamp as tick if provided

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'txstatsd/stats/exponentiallydecayingsample.py'
2--- txstatsd/stats/exponentiallydecayingsample.py 2012-03-07 20:20:52 +0000
3+++ txstatsd/stats/exponentiallydecayingsample.py 2012-05-11 06:12:19 +0000
4@@ -1,7 +1,7 @@
5-import bisect
6-import math
7-import random
8-import time
9+from time import time
10+from random import random
11+from math import exp
12+from bisect import insort
13
14
15 class ExponentiallyDecayingSample(object):
16@@ -30,17 +30,12 @@
17 @parama alpha: The exponential decay factor; the higher this is,
18 the more biased the sample will be towards newer values.
19 """
20- self._values = []
21 self.alpha = alpha
22 self.reservoir_size = reservoir_size
23
24- self.count = 0
25- self.start_time = 0
26- self.next_scale_time = 0
27-
28 if wall_time is None:
29- wall_time = time.time
30- self._wall_time = wall_time
31+ wall_time = time
32+ self.tick = wall_time
33 self.clear()
34
35 def clear(self):
36@@ -48,7 +43,7 @@
37 self.count = 0
38 self.start_time = self.tick()
39 self.next_scale_time = (
40- self._wall_time() + self.RESCALE_THRESHOLD)
41+ self.tick() + self.RESCALE_THRESHOLD)
42
43 def size(self):
44 return min(self.reservoir_size, self.count)
45@@ -60,35 +55,27 @@
46 @param timestamp: The epoch timestamp of *value* in seconds.
47 """
48
49- now = self._wall_time()
50- next = self.next_scale_time
51- if now >= next:
52- self.rescale(now, next)
53-
54 if timestamp is None:
55 timestamp = self.tick()
56-
57- priority = self.weight(timestamp - self.start_time) / random.random()
58- self.count += 1
59- new_count = self.count
60- if new_count <= self.reservoir_size:
61- bisect.insort(self._values, (priority, value))
62+ now = timestamp
63+
64+ if now >= self.next_scale_time:
65+ self.rescale(now, self.next_scale_time)
66+
67+ priority = exp(self.alpha * (timestamp - self.start_time)) / random()
68+ values = self._values
69+
70+ if self.count < self.reservoir_size:
71+ self.count += 1
72+ insort(values, (priority, value))
73 else:
74- first = self._values[0][0]
75-
76- if first < priority:
77- bisect.insort(self._values, (priority, value))
78- self._values = self._values[1:]
79-
80+ if values[0][0] < priority:
81+ insort(values, (priority, value))
82+ values.pop(0)
83+
84 def get_values(self):
85 return [v for (k, v) in self._values]
86
87- def tick(self):
88- return self._wall_time()
89-
90- def weight(self, t):
91- return math.exp(self.alpha * t)
92-
93 def rescale(self, now, next):
94 """
95 A common feature of the above techniques - indeed, the key technique
96@@ -112,13 +99,12 @@
97 pass over whatever data structure is being used.
98 """
99
100- self.next_scale_time = (
101- now + self.RESCALE_THRESHOLD)
102+ self.next_scale_time = (now + self.RESCALE_THRESHOLD)
103 old_start_time = self.start_time
104- self.start_time = self.tick()
105+ self.start_time = now
106
107 new_values = []
108 for k, v in self._values:
109- nk = k * math.exp(-self.alpha * (self.start_time - old_start_time))
110- new_values.append((nk, v))
111+ nk = k * exp(-self.alpha * (self.start_time - old_start_time))
112+ insort(new_values, (nk, v))
113 self._values = new_values

Subscribers

People subscribed via source and target branches