Optimizing Memory Allocation in a Simple, but Long Function
Chris Angelico
rosuav at gmail.com
Sun Apr 24 14:21:51 EDT 2016
On Mon, Apr 25, 2016 at 4:03 AM, Derek Klinge <schilke.60 at gmail.com> wrote:
> Ok, from the gmail web client:
Bouncing this back to the list, and removing quote markers for other
people's copy/paste convenience.
## Write a method to approximate Euler's Number using Euler's Method
import math
class EulersNumber():
def __init__(self,n):
self.eulerSteps = n
self.e = self.EulersMethod(self.eulerSteps)
def linearApproximation(self,x,h,d): # f(x+h)=f(x)+h*f'(x)
return x + h * d
def EulersMethod(self, numberOfSteps): # Repeate linear
approximation over an even range
e = 1 # e**0 = 1
for step in range(numberOfSteps):
e = self.linearApproximation(e,1.0/numberOfSteps,e) # if
f(x)= e**x, f'(x)=f(x)
return e
def EulerStepWithGuess(accuracy,guessForN):
n = guessForN
e = EulersNumber(n)
while abs(e.e - math.e) > abs(accuracy):
n +=1
e = EulersNumber(n)
print('n={} \te= {} \tdelta(e)={}'.format(n,e.e,abs(e.e - math.e)))
return e
def EulersNumberToAccuracy(PowerOfTen):
x = 1
theGuess = 1
thisE = EulersNumber(1)
while x <= abs(PowerOfTen):
thisE = EulerStepWithGuess(10**(-1*x),theGuess)
theGuess = thisE.eulerSteps * 10
x += 1
return thisE
> To see an example of my problem try something like EulersNumberToAccuracy(-10)
Yep, I see it.
I invoked your script as "python3 -i euler.py" and then made that call
interactively. It quickly ran through the first few iterations, and
then had one CPU core saturated; but at no time did memory usage look
too bad. You may be correct in Python 2, though - it started using
about 4GB of RAM (not a problem to me - I had about 9GB available when
I started it), and then I halted it.
The Python 3 version has been running for a few minutes now.
n=135914023 e= 2.718281818459972 delta(e)=9.999073125044333e-09
'top' says:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7467 rosuav 20 0 32432 9072 4844 R 100.0 0.1 3:58.44 python3
In other words, it's saturating one CPU core ("%CPU 100.0"), but its
memory usage (VIRT/RES/SHR) is very low. At best, this process can be
blamed for 0.1% of memory.
Adding these lines to the top makes it behave differently in Python 2:
try: range = xrange
except NameError: pass
The Py3 behaviour won't change, but Py2 should now have the same kind
of benefit (the xrange object is an iterable that doesn't need a
concrete list of integers).
ChrisA
More information about the Python-list
mailing list