From: Patrick Maupin on
On Apr 5, 6:50 pm, Ethan Furman <et...(a)stoneleaf.us> wrote:

(Posted some code with a timeit...)

Well, I'm not going to debug this, but with the *original* thing you
posted, and the thing I posted, with a call and everything (more
realistic scenario), the exception version seems slower on my machine:

#!/usr/bin/env python

import timeit

def frobnicate(a,b,c,d):
pass

def heavy_lifting_at_runtime():
print 'heavy'

class spam_except(object):
def __call__(self, x, y, z):
try:
mongo = self.mongo
except AttributeError:
mongo = self.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, mongo)
se = spam_except()


class spam_if(object):
def __getattr__(self, name):
if name != 'mongo':
raise AttributeError
self.mongo = heavy_lifting_at_runtime()
return self.mongo
def __call__(self, x, y, z):
return frobnicate(x, y, z, self.mongo)
si = spam_if()

tse = timeit.Timer('se(1,2,3)', "from __main__ import se")
tsi = timeit.Timer('si(1,2,3)', "from __main__ import si")

for i in range(5):
ve = tse.timeit(10000000)
vi = tsi.timeit(10000000)
print ve, vi, '%.1f' % ((ve-vi) / vi * 100)

------

heavy
heavy
5.45695090294 5.10844397545 6.8
5.43381404877 5.01345705986 8.4
5.42474508286 5.02641201019 7.9
5.40713405609 5.04178905487 7.2
5.38063693047 4.96194696426 8.4

The output indicates that the exception one is, on average, around
7.5% slower.

Regards,
Pat
From: Albert van der Horst on
In article <mailman.1441.1270165718.23598.python-list(a)python.org>,
Steve Holden <steve(a)holdenweb.com> wrote:
>Terry Reedy wrote:
>> On 4/1/2010 6:34 PM, kj wrote:
>>>
>>>
>>> When coding C I have often found static local variables useful for
>>> doing once-only run-time initializations. For example:
>>>
>>> int foo(int x, int y, int z) {
>>>
>>> static int first_time = TRUE;
>>> static Mongo *mongo;
>>> if (first_time) {
>>> mongo = heavy_lifting_at_runtime();
>>> first_time = FALSE;
>>> }
>>>
>>> return frobnicate(mongo, x, y, z);
>>
>> Global var or class or closure such as below (obviously untested ;=):
>>
>> make_foo()
>> mongo = heavy_lifting_at_runtime();
>> def _(x,y,z):
>> return frobnicate(mongo, x, y, z)
>> return _
>> foo = make_foo
>
>I suspect you mean
>
>foo = make_foo()
>
>> del make_foo # to make sure it is *never* called again ;
>>
>> Now you only have foo with a hard-to-access private object and no
>> first_time checks when you call it.
>>
>> Terry Jan Reedy
>>
>I don't think I'd ever want to use such an obscure technique in a
>program. You might want to consider using functools.wraps to make sure
>that the foo function looks right.

Imagine that heavy_lifting is only ever used here and uses 4 Gbyte of core.
Suddenly deleting those function objects seems the right thing to do,
instead of an obscure technique.
(I'm not sure the Python compiler could take advantage of this,
I know I could in my Forth compiler, under circumstances.)

>
>regards
> Steve
>--
>Steve Holden +1 571 484 6266 +1 800 494 3119

Groetjes Albert

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert(a)spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst