Re: [Zope-dev] an Interface expressing a list of generator function

2010-11-09 Thread Jim Fulton
On Tue, Nov 9, 2010 at 2:58 AM, Jean-Daniel jeandaniel.bro...@gmail.com wrote:
 Ok,
 If I attach an item_type to the the list, I do not think I will able to use
 the native Python list, and should use a subclass instead. It is a bit
 heavyweight, especially when the intent of the use of the interface was
 documentation.

Tres could have avoided the generalization and just said something like:

class IGeneratorList(Interface):
A sequence of generators.

def __getitem__(index):
 Return the 'index'th item.

'index' must be an integer between 0 and __len__() - 1,
else raise IndexError.


blah blah...

Note that zope interfaces are only *semi*-formal.

 List and generators are very common in Python and are expressed in very few
 and clear characters,

Huh? What does this mean?

 I thought there would be a shorter  way to document
 their interfaces.

What exactly are you hoping to accomplish?

Jim

--
Jim Fulton
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] zope.interface memory optimization

2010-11-09 Thread Charlie Clark
Am 08.11.2010, 15:35 Uhr, schrieb Brian Sutherland  
br...@vanguardistas.net:

 If no-one replies, I'll assume that 3% is just not enough to be
 interesting and do nothing;)

Hi Brian,

thanks for sharing this but it looks to me like a micro-optimisation that  
isn't really worth going against best practice for - by using explicit  
name-mangling.

-return self.__tagged_values.get(tag, default)
+return getattr(self, '_Element__tagged_values', {}).get(tag,  
default)

Any improvements higher up the stack (using slots, different Python  
version or compilers like LLVM) are likely to have a more significant  
effect. Might be worth timing a slots-based implementation.

Charlie
-- 
Charlie Clark
Managing Director
Clark Consulting  Research
German Office
Helmholtzstr. 20
Düsseldorf
D- 40215
Tel: +49-211-600-3657
Mobile: +49-178-782-6226
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] zope.interface memory optimization

2010-11-09 Thread Brian Sutherland
On Tue, Nov 09, 2010 at 01:21:00AM +0200, Marius Gedminas wrote:
 On Mon, Nov 08, 2010 at 03:35:09PM +0100, Brian Sutherland wrote:
  I've committed 2 patches to a jinty-mem branch of zope.interface.
  Together these patches reduce the startup memory use of my ZTK based
  application by 3%. Is that enough to justify their risk/complexity?
  
  https://mail.zope.org/pipermail/checkins/2010-November/052516.html
  https://mail.zope.org/pipermail/checkins/2010-November/052517.html
  
  If no-one replies, I'll assume that 3% is just not enough to be
  interesting and do nothing;)
 
 It's so interesting I'm going to ask for even more numbers: how much is
 that 3% in kilobytes, or objects?

Ok, you asked for it ;)

The 3% was in kilobytes as measured using /bin/ps on OSX leopard with
python2.6 from MacPorts. The app I measured is a ZTK 1.0 based web
application.

My application without the changes:
Objects:245614
RSS memory (kb):59116

My application with the changes:
Objects:227147
RSS memory (kb):57180

I also did a micro-benchmark (more below) which indicate that when
creating an interface with 5 attributes and 5 methods you save 41% in
kilobytes and 34% in objects. 

 Is there any measurable speed impact
 for application startup or test runs (faster/slower)?

My app doesn't startup measurably faster or slower. The ZTK tests seem
to run a little faster, but the error is high on my laptop:

Without patches:
./bin/test-ztk  71.93s
./bin/test-ztk  70.49s
./bin/test-ztk  70.31s

With patches:
./bin/test-ztk  70.28s
./bin/test-ztk  70.00s
./bin/test-ztk  69.98s

I also did some micro-benchmarking (script is attached). There were
repeatable results which indicate that startup will be faster and
runtime only probably faster:

Without patches:

Performance bench
-
one interface, 5 methods, 5 functions: 181.00 usec/pass
five inheriting interfaces: 355.76 usec/pass
one interface: 59.79 usec/pass
query uninitialized tagged value: 1.26 usec/pass
query initialized tagged value: 1.27 usec/pass

Memory bench

Memory before (kb):
   RSS  VSZ
 33684   109780
objects created: 150001
Memory after (kb):
   RSS  VSZ
 47856   124116

With patches:

Performance bench
-
one interface, 5 methods, 5 functions: 165.97 usec/pass
five inheriting interfaces: 341.22 usec/pass
one interface: 53.03 usec/pass
query uninitialized tagged value: 0.75 usec/pass
query initialized tagged value: 1.37 usec/pass

Memory bench

Memory before (kb):
   RSS  VSZ
 33328   109524
objects created: 99001
Memory after (kb):
   RSS  VSZ
 41728   117972

 Otherwise I'm +1, assuming this doesn't somehow make the code 10%
 slower.
 
 Marius Gedminas
 -- 
 http://pov.lt/ -- Zope 3/BlueBream consulting and development



 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
  https://mail.zope.org/mailman/listinfo/zope-announce
  https://mail.zope.org/mailman/listinfo/zope )


-- 
Brian Sutherland
#
# Perdormance Benchmark
#

import os
import timeit
import subprocess
from zope.interface import Interface, Attribute
print Performance bench
print -

s1 = \
class I1(Interface):
a1 = Attribute('one')
a2 = Attribute('two')
a3 = Attribute('thee')
a4 = Attribute('four')
a5 = Attribute('five')
def f1(arg):
pass
def f2(arg):
pass
def f3(arg):
pass
def f4(arg):
pass
def f5(arg):
pass


t = timeit.Timer(stmt=s1, setup=from zope.interface import Interface, 
Attribute)
print one interface, 5 methods, 5 functions: %.2f usec/pass % (100 * 
t.timeit(number=1)/1)

s1 = \
class I1(Interface):
pass
class I2(I1):
pass
class I3(I2):
pass
class I4(I3):
pass
class I5(I4):
pass


t = timeit.Timer(stmt=s1, setup=from zope.interface import Interface, 
Attribute)
print five inheriting interfaces: %.2f usec/pass % (100 * 
t.timeit(number=1)/1)

s1 = \
class I1(Interface):
pass


t = timeit.Timer(stmt=s1, setup=from zope.interface import Interface, 
Attribute)
print one interface: %.2f usec/pass % (100 * t.timeit(number=1)/1)

setup = \
from zope.interface import Interface, Attribute
class I1(Interface):
pass


s1 = \
I1.queryTaggedValue('bob')

t = timeit.Timer(stmt=s1, setup=setup)
print query uninitialized tagged value: %.2f usec/pass % (100 * 
t.timeit(number=5)/5)

setup = \
from zope.interface import Interface, Attribute
class I1(Interface):
pass
I1.setTaggedValue('bob', 'bobby')


s1 = \
I1.queryTaggedValue('bob')

t = timeit.Timer(stmt=s1, setup=setup)
print 

Re: [Zope-dev] an Interface expressing a list of generator function

2010-11-09 Thread Jean-Daniel

 What exactly are you hoping to accomplish?


In brief, I wish there were a concise and clear way to express that an
object implements a list of generator functions, in the context of CS
students learning the concept of interface.

I am writing an article on a sudoku solver for an audience of CS
students, They do not know much of Python, have recently heard about
recursivity and the yield keyword was not obvious for them. The goal is that
they meet a nice collaboration between three objects, in Python, to
manipulate the concepts of code reuse and interface.

There is 1. a Sudoku class modelling a sudoku board and rules,
2. a backtracking algorithm,
3. and a function which returns the data structure (a list of generator
functions) used by the backtracking algorithm, and which uses an instance of
the Sudoku class,

(The solver code can be read at
jdb.github.com/modules/sudoku.htmlhttp://jdb.github.com/modules/sudoku.html#Sudoku,
a draft of the article is at : jdb.github.com/sudoku.html, the nice
backtracking algorithm comes from the conjoin algorithm described in
test_generators.py in the Python sources)

As the naive implementation the students would write is one big fat
function, I have to convince them that going through a more sophisticated
design is a better path. The idea is to exemplify code reuse by swapping the
Sudoku class with an optimized equivalent class, for instance. Also the same
backtracking algorithm can cook a solution to the eight queens problems or
the knight's tour problem, without modification but given the adapted list
of generator functions.

The interfaces help designing formalizing the collaboration between objects
and the article wishes to convey this idea. The Sudoku interface is nice and
clean but explaining the interface for a list of generator functions is
likely to raise more questions from the student than it brings clarity.
The interface will require the students to know that list and its bracket
notation implies the __getitem__ function, and that generator implies
__iter__ and next(). Roughly a dozen elegant lines are needed to implement
the interface with the Python keywords and syntax but the expected
__getitem__, __iter__ and next() will be absent from the implementation
which uses [] and yield.

I understand that the interfaces presented by Tres Seaver will work well for
the purpose of code reuse in a real application, and it is the way to go if
I want to use a global registry and/or a validation of the interface
provided by a class. At this point, I think it is easier to explain the
interface in plain english in the documentation with the help of the sphinx
documentation directives extracting the public methods of the class.

Here is (maybe) what I wish I could write:


from zope.interface import IList, IGenerator, Interface, provides, validates

def make_generator_functions():
[...]

make_generator_functions = , make_generator_functions)

def stack_assumption(gen_funcs):
validates(IList(IGenerator), gen_funcs)

[ ... ]


Thanks for your attention,



 Jim

 --
 Jim Fulton

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] an Interface expressing a list of generator function

2010-11-09 Thread Jean-Daniel
The end of the last message was not finished...


Ideally, here is (maybe) what I wish I could write:



from zope.interface import IList, IGenerator, implements, requires
def make_generator_functions():
implements(IList(IGenerator))
[...]

def stack_assumption(gen_funcs):
requires(IList(IGenerator), gen_funcs)
[ ... ]


Regards,
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] zope.interface memory optimization

2010-11-09 Thread Brian Sutherland
On Tue, Nov 09, 2010 at 03:49:38PM +0100, Charlie Clark wrote:
 Am 08.11.2010, 15:35 Uhr, schrieb Brian Sutherland  
 br...@vanguardistas.net:
 
  If no-one replies, I'll assume that 3% is just not enough to be
  interesting and do nothing;)
 
 Hi Brian,
 
 thanks for sharing this but it looks to me like a micro-optimisation that  
 isn't really worth going against best practice for - by using explicit  
 name-mangling.
 
 -return self.__tagged_values.get(tag, default)
 +return getattr(self, '_Element__tagged_values', {}).get(tag,  
 default)

In response to Marius' comments I changed the patch a bit earlier to
this:

def queryTaggedValue(self, tag, default=None):
 Returns the value associated with 'tag'. 
tv = self.__tagged_values
if tv is None:
return default
return tv.get(tag, default)

Which is is faster as well as not doing the explicit name mangling you
object to.
 
 Any improvements higher up the stack (using slots, different Python  
 version or compilers like LLVM) are likely to have a more significant  
 effect.

That would be great, when it arrives.

Actually, in my case, memory is the issue. So the only optimization
that'll really help in a big way is if multiple python processes running
similar code start sharing data.

Some people have poked at that problem, but I havn't seen anything
significant yet.

 Might be worth timing a slots-based implementation.

I just tried to add slots to Element, Attribute and Method classes, but
it there's too many tests that break to benchmark it running the ZTK
tests.

On the micro benchmarks, the only difference I see is a memory
improvement which I think will not survive in practice because most 

 Charlie
 -- 
 Charlie Clark
 Managing Director
 Clark Consulting  Research
 German Office
 Helmholtzstr. 20
 Düsseldorf
 D- 40215
 Tel: +49-211-600-3657
 Mobile: +49-178-782-6226
 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
  https://mail.zope.org/mailman/listinfo/zope-announce
  https://mail.zope.org/mailman/listinfo/zope )

-- 
Brian Sutherland
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] SVN: zope.interface/branches/jinty-mem/src/zope/interface/interface.py Improve CPU performance of previous memory optimization

2010-11-09 Thread Tres Seaver
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/09/2010 08:26 AM, Wichert Akkerman wrote:
 On 11/9/10 14:22 , Brian Sutherland wrote:
 Log message for revision 118295:
Improve CPU performance of previous memory optimization

 Changed:
U   zope.interface/branches/jinty-mem/src/zope/interface/interface.py

 -=-
 Modified: zope.interface/branches/jinty-mem/src/zope/interface/interface.py
 ===
 --- zope.interface/branches/jinty-mem/src/zope/interface/interface.py
 2010-11-09 08:31:37 UTC (rev 118294)
 +++ zope.interface/branches/jinty-mem/src/zope/interface/interface.py
 2010-11-09 13:22:27 UTC (rev 118295)
 @@ -51,6 +51,7 @@
   # infrastructure in place.
   #
   #implements(IElement)
 +__tagged_values = None

   def __init__(self, __name__, __doc__=''):
   Create an 'attribute' description
 @@ -72,22 +73,27 @@

   def getTaggedValue(self, tag):
Returns the value associated with 'tag'. 
 -return getattr(self, '_Element__tagged_values', {})[tag]
 +if self.__tagged_values is None:
 +return default
 +return self.__tagged_values[tag]
 
 You can even optimise this further:
 
tv = self.__tagged_values
if tv is None:
return default
return tv[tv]
 
 that avoids a second attribute lookup. You may also want to benchmark 
 that versus using a __tagged_values={} on the class and doing a simple 
 return self.__tagged_values.get(tag, default_

- -1:  mutable class defaults are a bug magnet.


Tres.
- -- 
===
Tres Seaver  +1 540-429-0999  tsea...@palladion.com
Palladion Software   Excellence by Designhttp://palladion.com
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkzZlFUACgkQ+gerLs4ltQ5ZYQCfRyDUGofCMiER447yJjBeEduu
E5IAniZu6SbOmYZC0XJt/4WeXOY2u5oD
=cNXP
-END PGP SIGNATURE-

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] SVN: zope.interface/branches/jinty-mem/src/zope/interface/interface.py Improve CPU performance of previous memory optimization

2010-11-09 Thread Laurence Rowe
On 9 November 2010 18:35, Tres Seaver tsea...@palladion.com wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 On 11/09/2010 08:26 AM, Wichert Akkerman wrote:
 On 11/9/10 14:22 , Brian Sutherland wrote:
 Log message for revision 118295:
    Improve CPU performance of previous memory optimization

 Changed:
    U   zope.interface/branches/jinty-mem/src/zope/interface/interface.py

 -=-
 Modified: zope.interface/branches/jinty-mem/src/zope/interface/interface.py
 ===
 --- zope.interface/branches/jinty-mem/src/zope/interface/interface.py       
  2010-11-09 08:31:37 UTC (rev 118294)
 +++ zope.interface/branches/jinty-mem/src/zope/interface/interface.py       
  2010-11-09 13:22:27 UTC (rev 118295)
 @@ -51,6 +51,7 @@
       # infrastructure in place.
       #
       #implements(IElement)
 +    __tagged_values = None

       def __init__(self, __name__, __doc__=''):
           Create an 'attribute' description
 @@ -72,22 +73,27 @@

       def getTaggedValue(self, tag):
            Returns the value associated with 'tag'. 
 -        return getattr(self, '_Element__tagged_values', {})[tag]
 +        if self.__tagged_values is None:
 +            return default
 +        return self.__tagged_values[tag]

 You can even optimise this further:

        tv = self.__tagged_values
        if tv is None:
            return default
        return tv[tv]

 that avoids a second attribute lookup. You may also want to benchmark
 that versus using a __tagged_values={} on the class and doing a simple
 return self.__tagged_values.get(tag, default_

 - -1:  mutable class defaults are a bug magnet.

None is immutable so I don't think that is a problem in this case.

I think the is a possible threading issue with Element.setTaggedValue
and Specification.subscribe - if two threads called the method
concurrently, then one of the values might be lost. I think the
correct way to do it would be:

tv = self.__tagged_values
if tv is None:
tv = self.__dict__.setdefault('_Element__tagged_values', {})
tv[tag] = value

This does bring the name mangling back though.

Laurence
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] zope.interface memory optimization

2010-11-09 Thread Marius Gedminas
On Tue, Nov 09, 2010 at 05:04:11PM +0100, Brian Sutherland wrote:
  Might be worth timing a slots-based implementation.
 
 I just tried to add slots to Element, Attribute and Method classes, but
 it there's too many tests that break to benchmark it running the ZTK
 tests.
 
 On the micro benchmarks, the only difference I see is a memory
 improvement which I think will not survive in practice because most 

... ?


Marius Gedminas
-- 
http://pov.lt/ -- Zope 3/BlueBream consulting and development


signature.asc
Description: Digital signature
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] zope.interface memory optimization

2010-11-09 Thread Brian Sutherland
On Wed, Nov 10, 2010 at 12:14:54AM +0200, Marius Gedminas wrote:
 On Tue, Nov 09, 2010 at 05:04:11PM +0100, Brian Sutherland wrote:
   Might be worth timing a slots-based implementation.
  
  I just tried to add slots to Element, Attribute and Method classes, but
  it there's too many tests that break to benchmark it running the ZTK
  tests.
  
  On the micro benchmarks, the only difference I see is a memory
  improvement which I think will not survive in practice because most 
 
 ... ?

Er, somehow my thoughts didn't make it into text:

attributes are zope.schema fields (i.e. subclasses of Attribute).

To really make that work, you'd have to add __slots__ to most of the
classes in zope.schema as well.

 
 
 Marius Gedminas
 -- 
 http://pov.lt/ -- Zope 3/BlueBream consulting and development



 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
  https://mail.zope.org/mailman/listinfo/zope-announce
  https://mail.zope.org/mailman/listinfo/zope )


-- 
Brian Sutherland
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


[Zope-dev] logrotation/logreopening in ZTK-based applications

2010-11-09 Thread Christian Theune
Hi,

Zope 2 provides a command to ask it to re-open its log files thus 
supporting outside logrotation.

We have a ZTK-based app and found that the server provides neither 
signal handling to rotate logs nor a zopectl command. Does anybody 
remember wether this was ever built?

I see an old discussion on the Python list 
(http://mail.python.org/pipermail/python-dev/2006-January/059566.html) 
but no conclusion.

If this isn't in yet, does anybody know what the right place would be? 
(I guess the packages providing the main loops and configuring the 
process would be the right ones.)

Christian

-- 
Christian Theune · c...@gocept.com
gocept gmbh  co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )