Skip to content

Instantly share code, notes, and snippets.

@bbengfort
Last active October 19, 2015 12:58
Show Gist options
  • Save bbengfort/6ca6f7c5d71055026d94 to your computer and use it in GitHub Desktop.
Save bbengfort/6ca6f7c5d71055026d94 to your computer and use it in GitHub Desktop.
Keeping a running average with Python, see: http://invisibleblocks.com/2008/07/30/long-running-averages-without-the-sum-of-preceding-values/ for more information.
#!/usr/bin/env python
from __future__ import division
import sys
import time
import random
class Averager(object):
def __init__(self):
self.total = 0.0
self.count = 0
def __call__(self, x):
self.total += x
self.count += 1
return self.total / self.count
@property
def average(self):
return self.total / self.count
def __sizeof__(self):
return sys.getsizeof(self.total) + sys.getsizeof(self.count)
class LightAverager(object):
def __init__(self):
self.average = 0.0
self.count = 0
def __call__(self, x):
self.count += 1
self.average += (x - self.average) / self.count
def __sizeof__(self):
return sys.getsizeof(self.average) + sys.getsizeof(self.count)
if __name__ == "__main__":
SEED = random.randint(1,1000)
def timeit(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
finish = time.time()
return result, finish-start
return wrapper
@timeit
def test(factory):
random.seed(SEED)
averager = factory()
for x in xrange(1000000):
averager(random.randint(100000,9999999999))
return averager
heavy, htime = test(Averager)
light, ltime = test(LightAverager)
stfmt = "%s computed an average of %0.6f in %0.3f seconds and weighs %i bytes"
print stfmt % (heavy.__class__.__name__, heavy.average, htime, sys.getsizeof(heavy))
print stfmt % (light.__class__.__name__, light.average, ltime, sys.getsizeof(light))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment