Re: question about the id()

2005-05-17 Thread Peter Dembinski
Giovanni Bajo [EMAIL PROTECTED] writes:

 Peter Dembinski wrote:

 BTW, a typical performance optimization (not done automatically by
 python) is to hoist unchanging-value expressions out of loops, and
 obj.method is often such an expression, so you will this strategy
 when people try
 to squeeze extra performance from their programs.

 Good to know.  Is there any advanced optimizer for Python code,
 which would do such things for me (or suggest them, like pychecker
 does for readability)?


 Prove that a.f() would not change the meaning of a.f after its
 invokation is close to impossible.

Many things in Python programs cannot be proved.  But what about
suggesting optimisations, not doing them automatically?  

The similar case may be found in refactorization -- most things cannot
be proved, so the final decision is left to the programmer (and his
unit tests).

-- 
http://www.peter.dembinski.prv.pl
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-17 Thread Dan Sommers
On Tue, 17 May 2005 13:56:18 +0200,
Peter Dembinski [EMAIL PROTECTED] wrote:

 Giovanni Bajo [EMAIL PROTECTED] writes:
 Peter Dembinski wrote:
 
 BTW, a typical performance optimization (not done automatically by
 python) is to hoist unchanging-value expressions out of loops, and
 obj.method is often such an expression, so you will this strategy
 when people try
 to squeeze extra performance from their programs.
 
 Good to know.  Is there any advanced optimizer for Python code,
 which would do such things for me (or suggest them, like pychecker
 does for readability)?
 
 
 Prove that a.f() would not change the meaning of a.f after its
 invokation is close to impossible.

 Many things in Python programs cannot be proved.  But what about
 suggesting optimisations, not doing them automatically?  

At that point, you can do the optimization yourself:

class A:
def method( self ):
pass

a = A( )
m = a.method # optimize runtime lookups for a.method
for x in range( 10 ):
m( )

Regards,
Dan

-- 
Dan Sommers
http://www.tombstonezero.net/dan/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Andrew Dalke
kyo guan wrote:
   Can someone explain why the id() return the same value, and why
 these values are changing? Thanks you.

 a=A()
 id(a.f)
 11365872
 id(a.g)
 11365872


The Python functions f and g, inside of a class A, are
unbound methods.  When accessed through an instance what's
returned is a bound method.

 A.f
unbound method A.f
 A().f
bound method A.f of __main__.A instance at 0x64198
 

In your code you do a.f, which creates a new bound method.
After the id() call its ref-count goes to zero and its
memory is freed.  Next you do a.g which creates a new
bound method.  In this case it reuses the same memory location,
which is why you get the same id.

I know Python keeps free lists for some data types.  I
suspect bound method objects are tracked this way because
they are made/destroyed so frequently.  That would increase
the likelihood of you seeing the same id value.


 a.f is a.g
 False

This is the first time you have two bound methods at
the same time.  Previously a bound method was garbage
collected before the next one was created.

 id(a.f), id(a.g), id(b.f), id(b.g)
 (11492408, 11492408, 11492408, 11492408)
 a.f is a.g
 False
 id(a.f), id(a.g), id(b.f), id(b.g)
 (11365872, 11365872, 11365872, 11365872)


The memory locations changed.  Here's a conjecture that
fits the facts and is useful to help understand.

Suppose the free list is maintained as a stack, with
the most recently freed object at the top of the stack,
which is the first to be used for the next object.

The a.f is a.g creates two bound methods, one at
11492408 and the other at 11365872.  Once the 'is'
is done it dec-refs the two methods, a.f first and
a.g second.  In this case the ref counts go to zero
and the memory moved to the free list.  At this point
the stack looks like

[11365872, 11492408,  ... rest of stack ... ]

You then do a.f.  This pulls from the top of the
stack so you get 11365872 again.  The id() tells
you that, and then the object gets decrefed and
put back on the stack.


Andrew
[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Peter Dembinski
Skip Montanaro [EMAIL PROTECTED] writes:

 kyo Can someone explain why the id() return the same value, and
 kyo why these values are changing?

 Instance methods are created on-the-fly.  

So, the interpreter creates new 'point in address space' every time
there is object-dot-method invocation in program?  

-- 
http://www.peter.dembinski.prv.pl
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Andrew Dalke
Peter Dembinski wrote:
 So, the interpreter creates new 'point in address space' every time
 there is object-dot-method invocation in program?

Yes.  That's why some code hand-optimizes inner loops by hoisting
the bound objection creation, as

data = []
data_append = data.append
for x in some_other_data:
   work with x to make y 
  data_append(y)


Andrew
[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Bengt Richter
On Mon, 16 May 2005 18:30:47 +0200, Peter Dembinski [EMAIL PROTECTED] wrote:

Skip Montanaro [EMAIL PROTECTED] writes:

 kyo Can someone explain why the id() return the same value, and
 kyo why these values are changing?

 Instance methods are created on-the-fly.  

So, the interpreter creates new 'point in address space' every time
there is object-dot-method invocation in program?

Yes, but you can save the result of the obj.method expression (that's what it 
is,
an expression). E.g.,

 bound_method = obj.method

after that, you can write

 bound_method()

or
 obj.method()

(of course, you can pass arguments too, depending on the signature,
remembering that the self instance parameter is already bound in
and does not need to be passed again to a bound method)

The obj.method() call will re-evaluate the obj.method expression,
and the bound_method() call will just call the previously created
bound method.

BTW, a typical performance optimization (not done automatically by python)
is to hoist unchanging-value expressions out of loops, and obj.method is
often such an expression, so you will this strategy when people try
to squeeze extra performance from their programs.

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Bengt Richter
On Mon, 16 May 2005 16:57:12 GMT, Andrew Dalke [EMAIL PROTECTED] wrote:

Peter Dembinski wrote:
 So, the interpreter creates new 'point in address space' every time
 there is object-dot-method invocation in program?

Yes.  That's why some code hand-optimizes inner loops by hoisting
the bound objection creation, as

data = []
data_append = data.append
for x in some_other_data:
   work with x to make y 
  data_append(y)

Sorry about the me-too. I hadn't seen your post. I should know better ;-)

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Peter Dembinski
[EMAIL PROTECTED] (Bengt Richter) writes:

[snap]

So, the interpreter creates new 'point in address space' every time
there is object-dot-method invocation in program?

[optimization]

 BTW, a typical performance optimization (not done automatically by python)
 is to hoist unchanging-value expressions out of loops, and obj.method is
 often such an expression, so you will this strategy when people try
 to squeeze extra performance from their programs.

Good to know.  Is there any advanced optimizer for Python code, which
would do such things for me (or suggest them, like pychecker does 
for readability)?

-- 
http://www.peter.dembinski.prv.pl
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-16 Thread Giovanni Bajo
Peter Dembinski wrote:

 BTW, a typical performance optimization (not done automatically by
 python) is to hoist unchanging-value expressions out of loops, and
 obj.method is often such an expression, so you will this strategy
 when people try
 to squeeze extra performance from their programs.

 Good to know.  Is there any advanced optimizer for Python code, which
 would do such things for me (or suggest them, like pychecker does
 for readability)?


Prove that a.f() would not change the meaning of a.f after its invokation is
close to impossible.
-- 
Giovanni Bajo


-- 
http://mail.python.org/mailman/listinfo/python-list


question about the id()

2005-05-15 Thread kyo guan
HI ALL:

Can someone explain why the id() return the same value, and why these 
values are changing? Thanks you.

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32
Type help, copyright, credits or license for more information.
 class A(object):
... def f():
... pass
... def g():
... pass
...

 a=A()
 id(a.f)
11365872
 id(a.g)
11365872


 class B(object):
... def f():
... print 1
... def g():
... print 3
...
 b=B()
 id(b.f)
11365872
 id(b.g)
11365872
 id(a.f), id(a.g), id(b.f), id(b.g)
(11365872, 11365872, 11365872, 11365872)
 a.f is a.g
False
 id(a.f), id(a.g), id(b.f), id(b.g)
(11492408, 11492408, 11492408, 11492408)
 a.f is a.g
False
 id(a.f), id(a.g), id(b.f), id(b.g)
(11365872, 11365872, 11365872, 11365872)


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-15 Thread Skip Montanaro

kyo Can someone explain why the id() return the same value, and why
kyo these values are changing?

Instance methods are created on-the-fly.  In your example the memory
associated with the a.f bound method (not the same as the unbound method
A.f) is freed before you reference a.g.  That chunk of memory just happens
to get reused for the bound method associated with a.g.  Here's a
demonstration:

% python
Python 2.5a0 (#77, May 14 2005, 14:47:06) 
[GCC 3.3 20030304 (Apple Computer, Inc. build 1671)] on darwin
Type help, copyright, credits or license for more information.
 class A(object):
...   def f(): pass
...   def g(): pass
... 
 a = A()
 x = a.f
 y = a.g
 id(x)
17969240
 id(y)
17969440
 id(a.f)
17969400
 id(a.g)
17969400

Skip
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: question about the id()

2005-05-15 Thread kyo guan
HI Skip:

I want to check is there any change in the instance 's methods.
 a=A()
 a2=A()
 a.f == a2.f
False
 a.f is a2.f
False
 a.f is a.f
False

If the instance methods are create on-the-fly, how to do that? Thanks.

Kyo
 

 -Original Message-
 From: Skip Montanaro [mailto:[EMAIL PROTECTED] 
 Sent: Monday, May 16, 2005 11:09 AM
 To: kyo guan
 Cc: python-list@python.org
 Subject: Re: question about the id()
 
 
 kyo Can someone explain why the id() return the same 
 value, and why
 kyo these values are changing?
 
 Instance methods are created on-the-fly.  In your example the 
 memory associated with the a.f bound method (not the same as 
 the unbound method
 A.f) is freed before you reference a.g.  That chunk of memory 
 just happens to get reused for the bound method associated 
 with a.g.  Here's a
 demonstration:
 
 % python
 Python 2.5a0 (#77, May 14 2005, 14:47:06) 
 [GCC 3.3 20030304 (Apple Computer, Inc. build 1671)] on darwin
 Type help, copyright, credits or license for more 
 information.
  class A(object):
 ...   def f(): pass
 ...   def g(): pass
 ... 
  a = A()
  x = a.f
  y = a.g
  id(x)
 17969240
  id(y)
 17969440
  id(a.f)
 17969400
  id(a.g)
 17969400
 
 Skip

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: question about the id()

2005-05-15 Thread Bengt Richter
On Mon, 16 May 2005 11:28:31 +0800, kyo guan [EMAIL PROTECTED] wrote:

HI Skip:

   I want to check is there any change in the instance 's methods.
 a=A()
 a2=A()
 a.f == a2.f
False
 a.f is a2.f
False
 a.f is a.f
False

   If the instance methods are create on-the-fly, how to do that? Thanks.
You have to define exactly what you mean by the instance's methods first ;-)
a.f is an expression that when evaluated creates a bound method according to
the rules of doing that. You can check what function was found for creating
this bound method using the .im_func attribute -- i.e. a.f.im_func -- but that
is only valid for that particular bound method. A bound method is a first class
object that you can pass around or assign, so the function you might get from
a fresh a.f might differ from a previous a.f, e.g.,

  class A(object):
 ... def f(self): return 'f1'
 ...
  a=A()
  a2=A()
  a.f.im_func is a2.f.im_func
 True
Now save the bound method a.f
  af = a.f

And change the class A method
  A.f = lambda self: 'f2'

Both a and a2 dynamically create bound methods based on the new method (lambda 
above)
so the functions are actually the same identical one
  a.f.im_func is a2.f.im_func
 True

But the bound method we saved by binding it to af still is bound to the old 
method function,
so a new dynamically created one is not the same:
  af.im_func is a2.f.im_func
 False
  af.im_func
 function f at 0x02FA3CDC
  a.f.im_func
 function lambda at 0x02F99B1C
  a2.f.im_func
 function lambda at 0x02F99B1C

The .im_func function id's are shown in hex through the repr above. I.e., 
compare with:

  '0x%08X' % id(a2.f.im_func)
 '0x02F99B1C'
  '0x%08X' % id(af.im_func)
 '0x02FA3CDC'

HTH

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list