Re: expression in an if statement

2010-08-22 Thread Gregory Ewing

Thomas Jollans wrote:
What if set has side effects? A 
compiler could only exclude this possibility if it knew exactly what set 
will be at run time,


And also that 'a' remains bound to the same object, and that
object or anything reachable from it is not mutated in
any way that could affect the result of set(a). That's
quite a lot of information for an optimiser to deduce,
particularly in a language as dynamic as Python.

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


Re: expression in an if statement

2010-08-21 Thread alex23
John Nagle na...@animats.com wrote:
 I was talking to the Facebook guys doing the compiler for PHP, and they
 said that it was a huge win for them that PHP doesn't allow dynamically
 replacing a function.

I'm not sure if I call all that effort for a 50% speed increase a win.
PyPy is seeing speed increases of up to 15 times that of CPython 2.6.2
without reducing the flexibility of the language at all.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: expression in an if statement

2010-08-20 Thread John Nagle

On 8/18/2010 3:12 PM, Thomas Jollans wrote:

On Wednesday 18 August 2010, it occurred to John Nagle to exclaim:

On 8/18/2010 11:24 AM, ernest wrote:

Hi,

In this code:

if set(a).union(b) == set(a): pass

Does Python compute set(a) twice?


 CPython does.  Shed Skin might optimize.  Don't know
about Iron Python.


I doubt any actual Python implementation optimizes this -- how could it? The
object set is clearly being called twice, and it happens to be called with
the object a as a sole argument twice. What if set has side effects? A
compiler could only exclude this possibility if it knew exactly what set
will be at run time, which it can't.


   That just reflects the rather lame state of Python implementations.
For some other languages, there are JIT compilers that can optimize such
things.  If you rebind a function at run time, the compiled code has to
be invalidated and recompiled with the new binding.

   The HotSpot Java JIT compiler did this.  See

http://books.google.com/books?id=GBISkhhrHh8Cpg=PA786lpg=PA786dq=JIT+compiler+rebindingsource=blots=GhZa3XbrNusig=OVBOnu0vwlVN_B1QC6jc2ltHk_whl=enei=IhluTLCXOIymsQOW6vy1Cwsa=Xoi=book_resultct=resultresnum=9ved=0CDsQ6AEwCA#v=onepageqf=false

It's really tough to get this right. There's a huge overhead in
either performance or complexity for allowing rebinding of
functions during execution.  It's also a feature very seldom
used after program startup.

I was talking to the Facebook guys doing the compiler for PHP, and they
said that it was a huge win for them that PHP doesn't allow dynamically
replacing a function.

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


Re: expression in an if statement

2010-08-19 Thread Frederic Rentsch
On Thu, 2010-08-19 at 00:12 +0200, Thomas Jollans wrote:
 On Wednesday 18 August 2010, it occurred to John Nagle to exclaim:
  On 8/18/2010 11:24 AM, ernest wrote:
   Hi,
   
   In this code:
   
   if set(a).union(b) == set(a): pass
   
   Does Python compute set(a) twice?
  
  CPython does.  Shed Skin might optimize.  Don't know
  about Iron Python.
 
 I doubt any actual Python implementation optimizes this -- how could it? 

And why should it if a programmer uses its facilities inefficiently. I
would write

 if set(a).issuperset (b): pass

Frederic



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


Re: expression in an if statement

2010-08-19 Thread ernest
On 19 Ago, 08:40, Frederic Rentsch anthra.nor...@bluewin.ch wrote:
 On Thu, 2010-08-19 at 00:12 +0200, Thomas Jollans wrote:
  On Wednesday 18 August 2010, it occurred to John Nagle to exclaim:
   On 8/18/2010 11:24 AM, ernest wrote:
Hi,

In this code:

if set(a).union(b) == set(a): pass

Does Python compute set(a) twice?

       CPython does.  Shed Skin might optimize.  Don't know
   about Iron Python.

  I doubt any actual Python implementation optimizes this -- how could it?

 And why should it if a programmer uses its facilities inefficiently. I
 would write

  if set(a).issuperset (b): pass

 Frederic

Yes, maybe the example is silly, but situations like this arise
frequently and it's good to know.

Thanks for the answers.

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


expression in an if statement

2010-08-18 Thread ernest
Hi,

In this code:

if set(a).union(b) == set(a): pass

Does Python compute set(a) twice?
Thanks in advance.

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


Re: expression in an if statement

2010-08-18 Thread Peter Otten
ernest wrote:

 In this code:
 
 if set(a).union(b) == set(a): pass
 
 Does Python compute set(a) twice?

 a = abc
 b = def
 _set = set
 def set(x):
... print computing set(%r) % x
... return _set(x)
...
 if set(a).union(b) == set(a): pass
...
computing set('abc')
computing set('abc')

So yes, set(a) is computed twice.

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


Re: expression in an if statement

2010-08-18 Thread John Nagle

On 8/18/2010 11:24 AM, ernest wrote:

Hi,

In this code:

if set(a).union(b) == set(a): pass

Does Python compute set(a) twice?


   CPython does.  Shed Skin might optimize.  Don't know
about Iron Python.

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


Re: expression in an if statement

2010-08-18 Thread Thomas Jollans
On Wednesday 18 August 2010, it occurred to John Nagle to exclaim:
 On 8/18/2010 11:24 AM, ernest wrote:
  Hi,
  
  In this code:
  
  if set(a).union(b) == set(a): pass
  
  Does Python compute set(a) twice?
 
 CPython does.  Shed Skin might optimize.  Don't know
 about Iron Python.

I doubt any actual Python implementation optimizes this -- how could it? The 
object set is clearly being called twice, and it happens to be called with 
the object a as a sole argument twice. What if set has side effects? A 
compiler could only exclude this possibility if it knew exactly what set 
will be at run time, which it can't.

I expect that set and a have to be looked up twice, actually: 
set(a).union(b) might rebind either one of them. This would be considered a 
very rude and inappropriate thing to do, but Python usually guarantees to 
allow bad taste and behaviour.

I might be wrong on some points here, but this is what I expect the expression 
(set(a).union(b) == set(a)) has to do, in any conforming implementation of 
Python. Please correct me if I'm wrong.

  1. find out which object set refers to
  2. find out which object a refers to
  3. call (set) with the single positional argument (a), no keyword arguments
  4. get the attribute union of the return value of [3]
  5. find out which object b refers to
  6. call (.union) with the single positional argument (b).
  7. look up __eq__ in the __class__ of the return value of [6]
  8. find out which object set refers to
  9. find out which object a refers to
 10. call (set) with the single positional argument (a), no keyword arguments
 11. call [7] with two positional arguments: the return values [6]  [10]
 
I'm not 100% sure if there are any guarantees as to when (5) is taken care of 
-- what would happen if set(a) or even set(a).__getattr__ changed the global 
b?
My list there is obviously referring to Python 3.x, so there is no __cmp__ to 
worry about.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: expression in an if statement

2010-08-18 Thread Daniel Kluev
On Thu, Aug 19, 2010 at 9:12 AM, Thomas Jollans tho...@jollybox.de wrote:

 I doubt any actual Python implementation optimizes this -- how could it?
 The
 object set is clearly being called twice, and it happens to be called
 with
 the object a as a sole argument twice. What if set has side effects? A
 compiler could only exclude this possibility if it knew exactly what set
 will be at run time, which it can't.

 I expect that set and a have to be looked up twice, actually:
 set(a).union(b) might rebind either one of them. This would be considered
 a
 very rude and inappropriate thing to do, but Python usually guarantees to
 allow bad taste and behaviour.


Yep.

 def test():
... a = [1]
... b = [1]
... if set(a).union(b) == set(a): pass
...
 dis.dis(test)
  2   0 LOAD_CONST   1 (1)
  3 BUILD_LIST   1
  6 STORE_FAST   0 (a)

  3   9 LOAD_CONST   1 (1)
 12 BUILD_LIST   1
 15 STORE_FAST   1 (b)

  4  18 LOAD_GLOBAL  0 (set)
 21 LOAD_FAST0 (a)
 24 CALL_FUNCTION1
 27 LOAD_ATTR1 (union)
 30 LOAD_FAST1 (b)
 33 CALL_FUNCTION1
 36 LOAD_GLOBAL  0 (set)
 39 LOAD_FAST0 (a)
 42 CALL_FUNCTION1
 45 COMPARE_OP   2 (==)
 48 JUMP_IF_FALSE4 (to 55)
 51 POP_TOP
 52 JUMP_FORWARD 1 (to 56)
   55 POP_TOP
   56 LOAD_CONST   0 (None)
 59 RETURN_VALUE



 I might be wrong on some points here, but this is what I expect the
 expression
 (set(a).union(b) == set(a)) has to do, in any conforming implementation of
 Python. Please correct me if I'm wrong.


You can use dis module to let Python do compiling and explaining for you

-- 
With best regards,
Daniel Kluev
-- 
http://mail.python.org/mailman/listinfo/python-list