From: Kent J. <ke...@td...> - 2005-07-22 15:28:00
|
Leo User wrote: > Howdy, > > ok to the point, in jython-a0 I ran into the strangest behavior when I > was developing jyleo. I had a method that wrapped a position iterator > with a java.util.Iterator. This was all fine. But when I wrote out a > leo file the memory increased by 6%, each time!. I could not fathom > what was going on and had to instrument the jython implementation to get > visibility. What I found was somewhat startling, a new class was > generated each time the method was called. > > so a seemingly harmless method/closure like this: > def example(): > ...class example_closure: > ......pass > ...return example_closure() > > ended up eating up alot of memory. For methods that get called alot > this cant be used. For those that called a little its ok. But I must > ask, does anyone think this is normal behavior? We debated this on the > Leo forums and Edward Ream pointed out that class is an executable > statement, hence generating a new class each time was correct. I still > find myself debating the utility of such a mechanism, I find myself > saying "Jython Closures Considered Harmful". I would have to agree with Edward - class is an executable statement. CPython has the same behavior: >>> def example(): ... class example_closure: ... pass ... return example_closure() ... >>> a=example() >>> a.__class__ <class __main__.example_closure at 0x008CE960> >>> b=example() >>> b.__class__ <class __main__.example_closure at 0x008CEA50> If the nested class doesn't actually need the closure then just pull it out of the def: class example_closure: pass def example(): return example_closure() Alternately you could pass the relevant part of the closure to the example_closure() constructor: class example_closure: def __init__(self, state): self.state = state def example(state): return example_closure(state) Kent |