Re: Set Frozenset?

2009-03-11 Thread Lie Ryan

R. David Murray wrote:

Lie Ryan lie.1...@gmail.com wrote:

Matt Nordhoff wrote:

Alan G Isaac wrote:

Hans Larsen schrieb:
How could I take an elemment from a set or a frozenset 

On 3/8/2009 2:06 PM Diez B. Roggisch apparently wrote:

You iterate over them. If you only want one value, use
iter(the_set).next()

I recall a claim that

for result in myset: break

is the most efficient way to get one result.
Is this right? (It seems nearly the same.)

Alan Isaac

Checking Python 2.5 on Linux, your solution is much faster, but seeing
as they both come in under a microsecond, it hardly matters.


It's unexpected...

  timeit.timeit('res=iter(myset).next()', 'myset=range(100)')
0.8894412399647
  timeit.timeit('res=myset.next()', 'myset=range(100); 
myset=iter(myset)')

0.4916552002516
  timeit.timeit('for res in myset: break', 'myset=range(100)')
0.3293300797699

I'd never expect that for-loop assignment is even faster than a 
precreated iter object (the second test)... but I don't think this 
for-looping variable leaking behavior is guaranteed, isn't it?


My guess would be that what's controlling the timing here is
name lookup.  Three in the first example, two in the second,
and one in the third.


You got it:

 timeit.timeit('res=myset()', 'myset=range(100); 
myset=iter(myset).next')

0.2646590399796


--

The following is a complete benchmark:

 timeit.timeit('res=iter(myset).next()', 'myset=range(1000)', 
number=1000)

8.514500200432

 timeit.timeit('res=myset.next()', 'myset=range(1000); 
myset=iter(myset)', number=1000)

4.550980280898

 timeit.timeit('for res in myset: break', 'myset=range(1000)', 
number=1000)

2.999421360421

 timeit.timeit('res=myset()', 'myset=range(1000); 
myset=iter(myset).next', number=1000)

2.222883241011

--
I also performed additional timing for overhead:

Local name lookup:
 timeit.timeit('myset', 'myset=range(100)', number=1000)
1.108640079865

Global name lookup:
 timeit.timeit('iter', number=1000)
1.814941079259

Attribute lookup:
 timeit.timeit('myset.next', 'myset=range(1000); 
myset=iter(myset)', number=1000)

3.301133397987

Combined multiple name lookup that troubled first test
 timeit.timeit('iter(myset).next', 'myset=range(1000)', 
number=1000)

6.559937480305

Creating iterables:
 timeit.timeit('iter(myset)', 'myset=range(100)', number=1000)
4.25940671788

--
So adjusting the overheads:

Attribute lookup:
 timeit.timeit('myset.next', 'myset=range(1000); 
myset=iter(myset)', number=1000)

3.301133397987
The timing for Attribute also include a local name lookup (myset), so 
the real attribute lookup time shold be:

3.301133397987 - 1.108640079865 = 2.192493318122

Creating iterables:
 timeit.timeit('iter(myset)', 'myset=range(100)', number=1000)
4.25940671788
Creating iterable involve global name lookup, so the real time should be:
4.25940671788 - 1.814941079259 = 2.65638621

--
To summarize the adjusted overheads:

Local name lookup: 1.108640079865
Global name lookup: 1.814941079259
Attribute lookup: 2.192493318122
Creating iterables: 2.65638621

--
Back to the problem, now we'll be adjusting the timing of each codes:
'res=iter(myset).next()': 8.514500200432
Adjusting with the Combined multiple name lookup
8.514500200432 - 6.559937480305 = 1.954562720126
Another way to do the adjustment:
Adjusting global name lookup (iter):
8.514500200432 - 1.814941079259 = 6.699559121172
Adjusting iterable creation:
6.699559121172 - 2.65638621 = 4.255093482551
Adjusting attribute lookup:
4.255093482551 - 2.192493318122 = 2.062600164429

'res=myset.next()': 4.550980280898
Adjusting with |unadjusted| attribute lookup:
4.550980280898 - 3.301133397987 = 1.249846882911
Another way to do the adjustment:
Adjusting with local name lookup:
4.550980280898 - 1.108640079865 = 3.442340201033
Adjusting with attribute lookup:
3.442340201033 - 2.192493318122 = 1.249846882911

'for res in myset: break': 2.999421360421
Adjusting for local name lookup (myset):
2.999421360421 - 1.108640079865 = 1.890781280556

'res=myset()': 2.222883241011
Adjusting for local name lookup
2.222883241011 - 1.108640079865 = 1.114243161146

--

To summarize:
'res=iter(myset).next()': 1.954562720126 / 2.062600164429
'res=myset.next()': 1.249846882911 / 1.249846882911
'for res in myset: break': 1.890781280556
'res=myset()': 1.114243161146

--

To conclude, 'for res in myset: break' is actually not much faster than 
'res=iter(myset).next()' except the former saves a lot of name lookup. 
The problem with 

Re: Set Frozenset?

2009-03-10 Thread Lie Ryan

Matt Nordhoff wrote:

Alan G Isaac wrote:

Hans Larsen schrieb:
How could I take an elemment from a set or a frozenset 


On 3/8/2009 2:06 PM Diez B. Roggisch apparently wrote:

You iterate over them. If you only want one value, use
iter(the_set).next()


I recall a claim that

for result in myset: break

is the most efficient way to get one result.
Is this right? (It seems nearly the same.)

Alan Isaac


Checking Python 2.5 on Linux, your solution is much faster, but seeing
as they both come in under a microsecond, it hardly matters.



It's unexpected...

 timeit.timeit('res=iter(myset).next()', 'myset=range(100)')
0.8894412399647
 timeit.timeit('res=myset.next()', 'myset=range(100); 
myset=iter(myset)')

0.4916552002516
 timeit.timeit('for res in myset: break', 'myset=range(100)')
0.3293300797699

I'd never expect that for-loop assignment is even faster than a 
precreated iter object (the second test)... but I don't think this 
for-looping variable leaking behavior is guaranteed, isn't it?


Note: the second one exhausts the iter object.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Set Frozenset?

2009-03-10 Thread Terry Reedy

Lie Ryan wrote:


I recall a claim that

for result in myset: break

is the most efficient way to get one result.


I'd never expect that for-loop assignment is even faster than a 
precreated iter object (the second test)... but I don't think this 
for-looping variable leaking behavior is guaranteed, isn't it?


It is an intentional, documented feature:

Names in the target list are not deleted when the loop is finished, but 
if the sequence is empty, it will not have been assigned to at all by 
the loop.


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


Re: Set Frozenset?

2009-03-10 Thread Paul Rubin
Terry Reedy tjre...@udel.edu writes:
  I'd never expect that for-loop assignment is even faster than a
  precreated iter object (the second test)... but I don't think this
  for-looping variable leaking behavior is guaranteed, isn't it?
 
 It is an intentional, documented feature: ...

I prefer thinking of it as a documented bug.  It is fixed in 3.x.
I usually avoid the [... for x in xiter] listcomp syntax in favor of
list(... for x in xiter) just as an effort to be a bit less bug-prone.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Set Frozenset?

2009-03-10 Thread Terry Reedy

Paul Rubin wrote:

Terry Reedy tjre...@udel.edu writes:

I'd never expect that for-loop assignment is even faster than a
precreated iter object (the second test)... but I don't think this
for-looping variable leaking behavior is guaranteed, isn't it?

It is an intentional, documented feature: ...


I prefer thinking of it as a documented bug.  It is fixed in 3.x.


Nope to both. We are talking about for-loop statements.

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


Re: Set Frozenset?

2009-03-10 Thread R. David Murray
Lie Ryan lie.1...@gmail.com wrote:
 Matt Nordhoff wrote:
  Alan G Isaac wrote:
  Hans Larsen schrieb:
  How could I take an elemment from a set or a frozenset 
 
  On 3/8/2009 2:06 PM Diez B. Roggisch apparently wrote:
  You iterate over them. If you only want one value, use
  iter(the_set).next()
 
  I recall a claim that
 
  for result in myset: break
 
  is the most efficient way to get one result.
  Is this right? (It seems nearly the same.)
 
  Alan Isaac
  
  Checking Python 2.5 on Linux, your solution is much faster, but seeing
  as they both come in under a microsecond, it hardly matters.
 
 
 It's unexpected...
 
   timeit.timeit('res=iter(myset).next()', 'myset=range(100)')
 0.8894412399647
   timeit.timeit('res=myset.next()', 'myset=range(100); 
 myset=iter(myset)')
 0.4916552002516
   timeit.timeit('for res in myset: break', 'myset=range(100)')
 0.3293300797699
 
 I'd never expect that for-loop assignment is even faster than a 
 precreated iter object (the second test)... but I don't think this 
 for-looping variable leaking behavior is guaranteed, isn't it?

My guess would be that what's controlling the timing here is
name lookup.  Three in the first example, two in the second,
and one in the third.

--
R. David Murray   http://www.bitdance.com

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


Re: Set Frozenset?

2009-03-09 Thread Alan G Isaac

Hans Larsen schrieb:
How could I take an elemment from a set or a frozenset 



On 3/8/2009 2:06 PM Diez B. Roggisch apparently wrote:

You iterate over them. If you only want one value, use
iter(the_set).next()



I recall a claim that

for result in myset: break

is the most efficient way to get one result.
Is this right? (It seems nearly the same.)

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


Re: Set Frozenset?

2009-03-09 Thread Matt Nordhoff
Alan G Isaac wrote:
 Hans Larsen schrieb:
 How could I take an elemment from a set or a frozenset 
 
 
 On 3/8/2009 2:06 PM Diez B. Roggisch apparently wrote:
 You iterate over them. If you only want one value, use
 iter(the_set).next()
 
 
 I recall a claim that
 
 for result in myset: break
 
 is the most efficient way to get one result.
 Is this right? (It seems nearly the same.)
 
 Alan Isaac

Checking Python 2.5 on Linux, your solution is much faster, but seeing
as they both come in under a microsecond, it hardly matters.
-- 
--
http://mail.python.org/mailman/listinfo/python-list


Re: Set Frozenset?

2009-03-08 Thread Diez B. Roggisch

Hans Larsen schrieb:

Could you help me ?
How could I take an elemment from a set or a frozenset .-) ?

From a string (unicode? Python3), or from a tuple,or 
from a list: Element by index or slice.

From a dict: by key.
But what concerning a set or frozenset!

 hope somebody can help!


You iterate over them. If you only want one value, use


iter(the_set).next()

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


Re: Set Frozenset?

2009-03-08 Thread Tim Golden

Diez B. Roggisch wrote:

Hans Larsen schrieb:

Could you help me ?
How could I take an elemment from a set or a frozenset 
.-) ?


From a string (unicode? Python3), or from a 
tuple,or from a list: Element by index or slice.

From a dict: by key.
But what concerning a set or frozenset!

 hope somebody can help!


You iterate over them. If you only want one value, use


iter(the_set).next()


or the_set.pop ()

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


Re: Set Frozenset?

2009-03-08 Thread Tim Golden

Tim Golden wrote:

Diez B. Roggisch wrote:

Hans Larsen schrieb:

Could you help me ?
How could I take an elemment from a set or a frozenset 
.-) ?


From a string (unicode? Python3), or from a 
tuple,or from a list: Element by index or slice.

From a dict: by key.
But what concerning a set or frozenset!

 hope somebody can help!


You iterate over them. If you only want one value, use


iter(the_set).next()


or the_set.pop ()


Which will, in addition, remove it from the set.
(May not be what you want :) ).

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