Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #34288 > unrolled thread

why does dead code costs time?

Started byBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
First post2012-12-05 16:46 +0100
Last post2012-12-05 22:58 +0100
Articles 20 on this page of 22 — 12 participants

Back to article view | Back to comp.lang.python


Contents

  why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 16:46 +0100
    Re: why does dead code costs time? Neil Cerutti <neilc@norwich.edu> - 2012-12-05 16:15 +0000
      Re: why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 17:40 +0100
        Re: why does dead code costs time? Ramchandra Apte <maniandram01@gmail.com> - 2012-12-09 06:11 -0800
          Re: why does dead code costs time? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-12-09 16:47 +0000
            Re: why does dead code costs time? Ramchandra Apte <maniandram01@gmail.com> - 2012-12-12 21:23 -0800
              Re: why does dead code costs time? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-13 06:01 +0000
                Re: why does dead code costs time? rusi <rustompmody@gmail.com> - 2012-12-12 22:27 -0800
                  Re: why does dead code costs time? Cameron Simpson <cs@zip.com.au> - 2012-12-13 17:51 +1100
                    Re: why does dead code costs time? rusi <rustompmody@gmail.com> - 2012-12-12 22:59 -0800
                      Re: why does dead code costs time? Chris Angelico <rosuav@gmail.com> - 2012-12-13 18:03 +1100
            Re: why does dead code costs time? Ramchandra Apte <maniandram01@gmail.com> - 2012-12-12 21:23 -0800
      Re: why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 18:19 +0100
        Re: why does dead code costs time? Tim Roberts <timr@probo.com> - 2012-12-05 21:20 -0800
    Re: why does dead code costs time? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-05 17:34 +0000
      Re: why does dead code costs time? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-12-05 17:39 +0000
      Re: why does dead code costs time? Ian Kelly <ian.g.kelly@gmail.com> - 2012-12-05 10:59 -0700
      Re: why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 19:24 +0100
      Re: why does dead code costs time? Terry Reedy <tjreedy@udel.edu> - 2012-12-05 15:41 -0500
      Re: why does dead code costs time? Chris Kaynor <ckaynor@zindagigames.com> - 2012-12-05 12:49 -0800
      Re: why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 21:50 +0100
      Re: why does dead code costs time? Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> - 2012-12-05 22:58 +0100

Page 1 of 2  [1] 2  Next page →


#34288 — why does dead code costs time?

FromBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
Date2012-12-05 16:46 +0100
Subjectwhy does dead code costs time?
Message-ID<mailman.496.1354722393.29569.python-list@python.org>
Hi,

I'm interested in compilers optimizations, so I study python compilation process

I ran that script:

    import timeit

    def f(x):
        return None

    def g(x):
        return None
        print(x)

    number = 10000

    print(timeit.timeit('f(1)',setup="from __main__ import f", number=number))
    print(timeit.timeit('g(1)',setup="from __main__ import g", number=number))   

    print(dis.dis(f))
    print(dis.dis(g))

It gives this output:

    0.003460251959040761
    0.004164454061537981
     17           0 LOAD_CONST               0 (None) 
                  3 RETURN_VALUE         
    None
     20           0 LOAD_GLOBAL              0 (None) 
                  3 RETURN_VALUE         

     21           4 LOAD_GLOBAL              1 (print) 
                  7 LOAD_FAST                0 (x) 
                 10 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
                 13 POP_TOP              
    None

I do not understand why the dead code `print(x)` takes time (~20% in
that case). As we see in the opcode, a call to g(1) returns immediately, so
there should be no delay at all. Where am i wrong?

mmhh... it comes to me now that the gap must be in function loading time...
I'll check ceval.c

However, isn't there a room for a slight optim here? (in this case, the
dead code is obvious, but it may be hidden by complex loops and
conditions)

Cheers


-- 
Bruno Dupuis

[toc] | [next] | [standalone]


#34291

FromNeil Cerutti <neilc@norwich.edu>
Date2012-12-05 16:15 +0000
Message-ID<ai9a9vFaup4U2@mid.individual.net>
In reply to#34288
On 2012-12-05, Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> wrote:
> Hi,
>
> I'm interested in compilers optimizations, so I study python
> compilation process
>
> I ran that script:
>
>     import timeit
>
>     def f(x):
>         return None
>
>     def g(x):
>         return None
>         print(x)
>
>     number = 10000
>
>     print(timeit.timeit('f(1)',setup="from __main__ import f", number=number))
>     print(timeit.timeit('g(1)',setup="from __main__ import g", number=number))   
>
>     print(dis.dis(f))
>     print(dis.dis(g))
>
> It gives this output:
>
>     0.003460251959040761
>     0.004164454061537981
>      17           0 LOAD_CONST               0 (None) 
>                   3 RETURN_VALUE         
>     None
>      20           0 LOAD_GLOBAL              0 (None) 
>                   3 RETURN_VALUE         
>
>      21           4 LOAD_GLOBAL              1 (print) 
>                   7 LOAD_FAST                0 (x) 
>                  10 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
>                  13 POP_TOP              
>     None
>
> I do not understand why the dead code `print(x)` takes time (~20% in
> that case). As we see in the opcode, a call to g(1) returns immediately, so
> there should be no delay at all. Where am i wrong?
>
> mmhh... it comes to me now that the gap must be in function loading time...
> I'll check ceval.c
>
> However, isn't there a room for a slight optim here? (in this case, the
> dead code is obvious, but it may be hidden by complex loops and
> conditions)

Maybe it's the difference between LOAD_CONST and LOAD_GLOBAL. We
can wonder why g uses the latter.

-- 
Neil Cerutti

[toc] | [prev] | [next] | [standalone]


#34293

FromBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
Date2012-12-05 17:40 +0100
Message-ID<mailman.500.1354725646.29569.python-list@python.org>
In reply to#34291
On Wed, Dec 05, 2012 at 04:15:59PM +0000, Neil Cerutti wrote:
> On 2012-12-05, Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> wrote:
> > Hi,
> >
> > I'm interested in compilers optimizations, so I study python
> > compilation process
> >
> > I ran that script:
> >
> >     import timeit
> >
> >     def f(x):
> >         return None
> >
> >     def g(x):
> >         return None
> >         print(x)
> >
> >     number = 10000
> >
> >     print(timeit.timeit('f(1)',setup="from __main__ import f", number=number))
> >     print(timeit.timeit('g(1)',setup="from __main__ import g", number=number))   
> >
> >     print(dis.dis(f))
> >     print(dis.dis(g))
> >
> > It gives this output:
> >
> >     0.003460251959040761
> >     0.004164454061537981
> >      17           0 LOAD_CONST               0 (None) 
> >                   3 RETURN_VALUE         
> >     None
> >      20           0 LOAD_GLOBAL              0 (None) 
> >                   3 RETURN_VALUE         
> >
> >      21           4 LOAD_GLOBAL              1 (print) 
> >                   7 LOAD_FAST                0 (x) 
> >                  10 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
> >                  13 POP_TOP              
> >     None
> >
> > I do not understand why the dead code `print(x)` takes time (~20% in
> > that case). As we see in the opcode, a call to g(1) returns immediately, so
> > there should be no delay at all. Where am i wrong?
> >
> > mmhh... it comes to me now that the gap must be in function loading time...
> > I'll check ceval.c
> >
> > However, isn't there a room for a slight optim here? (in this case, the
> > dead code is obvious, but it may be hidden by complex loops and
> > conditions)
> 
> Maybe it's the difference between LOAD_CONST and LOAD_GLOBAL. We
> can wonder why g uses the latter.

Good point! I didn't even noticed that. It's weird... Maybe the
difference comes from a peehole optim on f which is not possible on g as
g is to complex.

> 
> -- 
> Neil Cerutti
> -- 
> http://mail.python.org/mailman/listinfo/python-list

-- 
Bruno Dupuis

[toc] | [prev] | [next] | [standalone]


#34522

FromRamchandra Apte <maniandram01@gmail.com>
Date2012-12-09 06:11 -0800
Message-ID<73029be5-a075-4eef-ad20-94b9fb3d6e56@googlegroups.com>
In reply to#34293
On Wednesday, 5 December 2012 22:10:51 UTC+5:30, Bruno Dupuis  wrote:
> On Wed, Dec 05, 2012 at 04:15:59PM +0000, Neil Cerutti wrote:
> 
> > On 2012-12-05, Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> wrote:
> 
> > > Hi,
> 
> > >
> 
> > > I'm interested in compilers optimizations, so I study python
> 
> > > compilation process
> 
> > >
> 
> > > I ran that script:
> 
> > >
> 
> > >     import timeit
> 
> > >
> 
> > >     def f(x):
> 
> > >         return None
> 
> > >
> 
> > >     def g(x):
> 
> > >         return None
> 
> > >         print(x)
> 
> > >
> 
> > >     number = 10000
> 
> > >
> 
> > >     print(timeit.timeit('f(1)',setup="from __main__ import f", number=number))
> 
> > >     print(timeit.timeit('g(1)',setup="from __main__ import g", number=number))   
> 
> > >
> 
> > >     print(dis.dis(f))
> 
> > >     print(dis.dis(g))
> 
> > >
> 
> > > It gives this output:
> 
> > >
> 
> > >     0.003460251959040761
> 
> > >     0.004164454061537981
> 
> > >      17           0 LOAD_CONST               0 (None) 
> 
> > >                   3 RETURN_VALUE         
> 
> > >     None
> 
> > >      20           0 LOAD_GLOBAL              0 (None) 
> 
> > >                   3 RETURN_VALUE         
> 
> > >
> 
> > >      21           4 LOAD_GLOBAL              1 (print) 
> 
> > >                   7 LOAD_FAST                0 (x) 
> 
> > >                  10 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
> 
> > >                  13 POP_TOP              
> 
> > >     None
> 
> > >
> 
> > > I do not understand why the dead code `print(x)` takes time (~20% in
> 
> > > that case). As we see in the opcode, a call to g(1) returns immediately, so
> 
> > > there should be no delay at all. Where am i wrong?
> 
> > >
> 
> > > mmhh... it comes to me now that the gap must be in function loading time...
> 
> > > I'll check ceval.c
> 
> > >
> 
> > > However, isn't there a room for a slight optim here? (in this case, the
> 
> > > dead code is obvious, but it may be hidden by complex loops and
> 
> > > conditions)
> 
> > 
> 
> > Maybe it's the difference between LOAD_CONST and LOAD_GLOBAL. We
> 
> > can wonder why g uses the latter.
> 
> 
> 
> Good point! I didn't even noticed that. It's weird... Maybe the
> 
> difference comes from a peehole optim on f which is not possible on g as
> 
> g is to complex.
> 
> 
> 
> > 
> 
> > -- 
> 
> > Neil Cerutti
> 
> > -- 
> 
> > http://mail.python.org/mailman/listinfo/python-list
> 
> 
> 
> -- 
> 
> Bruno Dupuis

peehole haha

[toc] | [prev] | [next] | [standalone]


#34524

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2012-12-09 16:47 +0000
Message-ID<mailman.657.1355071641.29569.python-list@python.org>
In reply to#34522
On 09/12/2012 14:11, Ramchandra Apte wrote:
>
> peehole haha
>

Double spaced crap from you again not so haha.

-- 
Cheers.

Mark Lawrence.

[toc] | [prev] | [next] | [standalone]


#34754

FromRamchandra Apte <maniandram01@gmail.com>
Date2012-12-12 21:23 -0800
Message-ID<2f87bbb0-c47d-4ceb-88aa-54df9146f282@googlegroups.com>
In reply to#34524
On Sunday, 9 December 2012 22:17:09 UTC+5:30, Mark Lawrence  wrote:
> On 09/12/2012 14:11, Ramchandra Apte wrote:
> 
> >
> 
> > peehole haha
> 
> >
> 
> Double spaced crap from you again not so haha.
> 
> -- 
> 
> Cheers.
> 
> Mark Lawrence.

haha. What does "Cheers" mean?

[toc] | [prev] | [next] | [standalone]


#34756

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-12-13 06:01 +0000
Message-ID<50c96f27$0$29868$c3e8da3$5496439d@news.astraweb.com>
In reply to#34754
On Wed, 12 Dec 2012 21:23:47 -0800, Ramchandra Apte wrote:

>> Cheers.
>> 
>> Mark Lawrence.
> 
> haha. What does "Cheers" mean?

It is an exclamation expressing good wishes. In particular, good wishes 
before drinking. Think of it as a variation on:

"Good health to you"
"Best wishes"
"Sincerest regards"

only less formal.


Does the Internet not work where you are? Googling for "define:cheers" or 
"definition cheers" should have answered that question.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#34759

Fromrusi <rustompmody@gmail.com>
Date2012-12-12 22:27 -0800
Message-ID<c53c665d-d4cb-43cc-8c33-765ca3ce86a4@m4g2000pbd.googlegroups.com>
In reply to#34756
On Dec 13, 11:01 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:
> On Wed, 12 Dec 2012 21:23:47 -0800, Ramchandra Apte wrote:
> >> Cheers.
>
> >> Mark Lawrence.
>
> > haha. What does "Cheers" mean?
>
> It is an exclamation expressing good wishes. In particular, good wishes
> before drinking. Think of it as a variation on:
>
> "Good health to you"
> "Best wishes"
> "Sincerest regards"
>
> only less formal.
>
> Does the Internet not work where you are? Googling for "define:cheers" or
> "definition cheers" should have answered that question.
>
> --
> Steven

One line above the "cheers" (with a double-space <wink>) we find:

> Double spaced crap from you again not so haha.

Do you find the sentiment expressed therein consistent with any of
your three meanings?

[toc] | [prev] | [next] | [standalone]


#34763

FromCameron Simpson <cs@zip.com.au>
Date2012-12-13 17:51 +1100
Message-ID<mailman.825.1355381490.29569.python-list@python.org>
In reply to#34759
On 12Dec2012 22:27, rusi <rustompmody@gmail.com> wrote:
| On Dec 13, 11:01 am, Steven D'Aprano <steve
| +comp.lang.pyt...@pearwood.info> wrote:
| > On Wed, 12 Dec 2012 21:23:47 -0800, Ramchandra Apte wrote:
| > >> Cheers.
| > >> Mark Lawrence.
| >
| > > haha. What does "Cheers" mean?
| >
| > It is an exclamation expressing good wishes. In particular, good wishes
| > before drinking. [...]
|
| One line above the "cheers" (with a double-space <wink>) we find:
| 
| > Double spaced crap from you again not so haha.
| 
| Do you find the sentiment expressed therein consistent with any of
| your three meanings?

Nope. But they're separate sentiments (weasel words:-)

I tend to end messages with "Cheers" myself. Though I also tend to strip
it out if I am being annoyed. As you say, it is inconsistent.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au>

It looked good-natured, she thought;  Still it had very long claws and a
great many teeth, so she felt it ought to be treated with respect.

[toc] | [prev] | [next] | [standalone]


#34764

Fromrusi <rustompmody@gmail.com>
Date2012-12-12 22:59 -0800
Message-ID<22d87cd2-9853-471f-ab76-978981b8a254@m4g2000pbd.googlegroups.com>
In reply to#34763
On Dec 13, 11:51 am, Cameron Simpson <c...@zip.com.au> wrote:
> It looked good-natured, she thought;  Still it had very long claws and a
> great many teeth, so she felt it ought to be treated with respect.

heh!

If only we could respect without such coercion(s)

[toc] | [prev] | [next] | [standalone]


#34766

FromChris Angelico <rosuav@gmail.com>
Date2012-12-13 18:03 +1100
Message-ID<mailman.827.1355382187.29569.python-list@python.org>
In reply to#34764
On Thu, Dec 13, 2012 at 5:59 PM, rusi <rustompmody@gmail.com> wrote:
> On Dec 13, 11:51 am, Cameron Simpson <c...@zip.com.au> wrote:
>> It looked good-natured, she thought;  Still it had very long claws and a
>> great many teeth, so she felt it ought to be treated with respect.
>
> heh!
>
> If only we could respect without such coercion(s)

Even if you don't respect his claws and teeth, you should respect the
fact that, as he says, "we're all mad here"...

But this is quite off topic, both off the thread's subject line and
the list's purpose.

ChrisA

[toc] | [prev] | [next] | [standalone]


#34755

FromRamchandra Apte <maniandram01@gmail.com>
Date2012-12-12 21:23 -0800
Message-ID<mailman.821.1355376230.29569.python-list@python.org>
In reply to#34524
On Sunday, 9 December 2012 22:17:09 UTC+5:30, Mark Lawrence  wrote:
> On 09/12/2012 14:11, Ramchandra Apte wrote:
> 
> >
> 
> > peehole haha
> 
> >
> 
> Double spaced crap from you again not so haha.
> 
> -- 
> 
> Cheers.
> 
> Mark Lawrence.

haha. What does "Cheers" mean?

[toc] | [prev] | [next] | [standalone]


#34296

FromBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
Date2012-12-05 18:19 +0100
Message-ID<mailman.503.1354727963.29569.python-list@python.org>
In reply to#34291
On Wed, Dec 05, 2012 at 05:40:51PM +0100, Bruno Dupuis wrote:
> On Wed, Dec 05, 2012 at 04:15:59PM +0000, Neil Cerutti wrote:
> > Maybe it's the difference between LOAD_CONST and LOAD_GLOBAL. We
> > can wonder why g uses the latter.
> 
> Good point! I didn't even noticed that. It's weird... Maybe the
> difference comes from a peehole optim on f which is not possible on g as
> g is to complex.
> 

Neil, you were right, thanks. I patched peehole.c to remove this optim, and
now the figures are the same. I investigate to find out why the latter
function is not optimized the same way (and if it can be, I'll propose a
patch for that)

-- 
Bruno Dupuis

[toc] | [prev] | [next] | [standalone]


#34363

FromTim Roberts <timr@probo.com>
Date2012-12-05 21:20 -0800
Message-ID<6ca0c8drtde9ick99lt0sh330mvj42qgh8@4ax.com>
In reply to#34296
Bruno Dupuis <python.ml.bruno.dupuis@lisael.org> wrote:

>On Wed, Dec 05, 2012 at 05:40:51PM +0100, Bruno Dupuis wrote:
> 
>> Good point! I didn't even noticed that. It's weird... Maybe the
>> difference comes from a peehole optim on f which is not possible on g as
>> g is to complex.
>
>Neil, you were right, thanks. I patched peehole.c to remove this optim, and
>now the figures are the same. I investigate to find out why the latter
>function is not optimized the same way (and if it can be, I'll propose a
>patch for that)

At the risk of being labeled a prude, please be careful about spelling (and
pronouncing) the whole word "peephole".  The word as you have spelled it
here (twice) is a vulgarity.

Now, I'm all in favor of the occasional vulgarity, but if this is a
misunderstanding, you could find yourself as the butt of some awkward jokes
at some future optimization conference...
-- 
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

[toc] | [prev] | [next] | [standalone]


#34297

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-12-05 17:34 +0000
Message-ID<50bf85c0$0$29994$c3e8da3$5496439d@news.astraweb.com>
In reply to#34288
On Wed, 05 Dec 2012 16:46:39 +0100, Bruno Dupuis wrote:

> Hi,
> 
> I'm interested in compilers optimizations, so I study python compilation
> process
> 
> I ran that script:
> 
>     import timeit
> 
>     def f(x):
>         return None
> 
>     def g(x):
>         return None
>         print(x)
> 
>     number = 10000
> 
>     print(timeit.timeit('f(1)',setup="from __main__ import f",
>     number=number)) print(timeit.timeit('g(1)',setup="from __main__
>     import g", number=number))
> 
>     print(dis.dis(f))
>     print(dis.dis(g))
> 
> It gives this output:
> 
>     0.003460251959040761
>     0.004164454061537981
>      17           0 LOAD_CONST               0 (None)
>                   3 RETURN_VALUE
>     None
>      20           0 LOAD_GLOBAL              0 (None)
>                   3 RETURN_VALUE
> 
>      21           4 LOAD_GLOBAL              1 (print)
>                   7 LOAD_FAST                0 (x)
>                  10 CALL_FUNCTION            1 (1 positional, 0 keyword
>                  pair) 13 POP_TOP
>     None
> 
> I do not understand why the dead code `print(x)` takes time (~20% in
> that case). As we see in the opcode, a call to g(1) returns immediately,
> so there should be no delay at all. Where am i wrong?

The difference is almost certain between the LOAD_CONST and the 
LOAD_GLOBAL.

As to *why* there is such a difference, I believe that's a leftover from 
early Python days when None was not a keyword and could be reassigned.


[steve@ando ~]$ python1.5
Python 1.5.2 (#1, Aug 27 2012, 09:09:18)  [GCC 4.1.2 20080704 (Red Hat 
4.1.2-52)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> from dis import dis
>>>
>>> def h():
...     x = 1
...     return None
...
>>> dis(h)
          0 SET_LINENO          1

          3 SET_LINENO          2
          6 LOAD_CONST          1 (1)
          9 STORE_FAST          0 (x)

         12 SET_LINENO          3
         15 LOAD_GLOBAL         1 (None)
         18 RETURN_VALUE
         19 LOAD_CONST          0 (None)
         22 RETURN_VALUE
>>> None = 42
>>> h()
42


Now that None is a keyword, it should always be a LOAD_CONST.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#34298

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-12-05 17:39 +0000
Message-ID<50bf86eb$0$29994$c3e8da3$5496439d@news.astraweb.com>
In reply to#34297
On Wed, 05 Dec 2012 17:34:57 +0000, Steven D'Aprano wrote:

> I believe that's a leftover from
> early Python days when None was not a keyword and could be reassigned.

Oops! Wrong copy and paste! Here's a simpler version:

[steve@ando ~]$ python1.5
Python 1.5.2 (#1, Aug 27 2012, 09:09:18)  [GCC 4.1.2 20080704 (Red Hat 
4.1.2-52)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> from dis import dis
>>> def h():
...     return None
...
>>> dis(h)
          0 SET_LINENO          1

          3 SET_LINENO          2
          6 LOAD_GLOBAL         0 (None)
          9 RETURN_VALUE
         10 LOAD_CONST          0 (None)
         13 RETURN_VALUE


The conclusion remains the same: calling LOAD_GLOBAL None is likely a 
fossil from ancient Python before it was a keyword.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#34302

FromIan Kelly <ian.g.kelly@gmail.com>
Date2012-12-05 10:59 -0700
Message-ID<mailman.510.1354730398.29569.python-list@python.org>
In reply to#34297
On Wed, Dec 5, 2012 at 10:34 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> The difference is almost certain between the LOAD_CONST and the
> LOAD_GLOBAL.
>
> As to *why* there is such a difference, I believe that's a leftover from
> early Python days when None was not a keyword and could be reassigned.

I think this should even be considered a bug, not just a missing
optimization.  Consider:

>>> globals()['None'] = 42
>>> def f(x):
...     return None
...     print(x)
...
>>> f('test')
42

The use of the LOAD_GLOBAL allows None to effectively be reassigned.

It's also worth noting that:

>>> def f(x):
...     return
...     print(x)
...
>>> dis.dis(f)
  2           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE

  3           4 LOAD_GLOBAL              0 (print)
              7 LOAD_FAST                0 (x)
             10 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             13 POP_TOP

So if you just write 'return' rather than 'return None', you get the
correct bytecode.  Additionally, the use of LOAD_GLOBAL instead of
LOAD_CONST seems to be linked to having unreachable code at the end of
the function.  This is fine:

>>> def f(x):
...     if x:
...         return None
...     print(x)
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 POP_JUMP_IF_FALSE       10

  3           6 LOAD_CONST               0 (None)
              9 RETURN_VALUE

  4     >>   10 LOAD_GLOBAL              1 (print)
             13 LOAD_FAST                0 (x)
             16 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             19 POP_TOP
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE

But this is not.  Note here that *both* loads of None become
LOAD_GLOBAL in this case:

>>> def f(x):
...     if x:
...         return None
...     return None
...     print(x)
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 POP_JUMP_IF_FALSE       13

  3           6 LOAD_GLOBAL              0 (None)
              9 RETURN_VALUE
             10 JUMP_FORWARD             0 (to 13)

  4     >>   13 LOAD_GLOBAL              0 (None)
             16 RETURN_VALUE

  5          17 LOAD_GLOBAL              1 (print)
             20 LOAD_FAST                0 (x)
             23 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             26 POP_TOP

[toc] | [prev] | [next] | [standalone]


#34309

FromBruno Dupuis <python.ml.bruno.dupuis@lisael.org>
Date2012-12-05 19:24 +0100
Message-ID<mailman.516.1354731848.29569.python-list@python.org>
In reply to#34297
On Wed, Dec 05, 2012 at 10:59:26AM -0700, Ian Kelly wrote:
> On Wed, Dec 5, 2012 at 10:34 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
> > The difference is almost certain between the LOAD_CONST and the
> > LOAD_GLOBAL.
> >
> > As to *why* there is such a difference, I believe that's a leftover from
> > early Python days when None was not a keyword and could be reassigned.
> 
> I think this should even be considered a bug, not just a missing
> optimization.  Consider:

This is definitely a bug

> >>> globals()['None'] = 42
> >>> def f(x):
> ...     return None
> ...     print(x)
> ...
> >>> f('test')
> 42

This one is pretty scary

The difference between `return None` and `return` leads to inconsistency and
is in contradiction with the specs, AFAIK. I'm glad we pointed this out.

-- 
Bruno Dupuis

[toc] | [prev] | [next] | [standalone]


#34322

FromTerry Reedy <tjreedy@udel.edu>
Date2012-12-05 15:41 -0500
Message-ID<mailman.522.1354740106.29569.python-list@python.org>
In reply to#34297
On 12/5/2012 1:24 PM, Bruno Dupuis wrote:
> On Wed, Dec 05, 2012 at 10:59:26AM -0700, Ian Kelly wrote:
>> On Wed, Dec 5, 2012 at 10:34 AM, Steven D'Aprano
>> <steve+comp.lang.python@pearwood.info> wrote:
>>> The difference is almost certain between the LOAD_CONST and the
>>> LOAD_GLOBAL.
>>>
>>> As to *why* there is such a difference, I believe that's a leftover from
>>> early Python days when None was not a keyword and could be reassigned.
>>
>> I think this should even be considered a bug, not just a missing
>> optimization.  Consider:
>
> This is definitely a bug
>
>>>>> globals()['None'] = 42
>>>>> def f(x):
>> ...     return None
>> ...     print(x)
>> ...
>>>>> f('test')
>> 42
>
> This one is pretty scary
>
> The difference between `return None` and `return` leads to inconsistency and
> is in contradiction with the specs, AFAIK. I'm glad we pointed this out.

You did not specify version, but I confirmed in 3.3.0. Please open a 
tracker issue.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#34323

FromChris Kaynor <ckaynor@zindagigames.com>
Date2012-12-05 12:49 -0800
Message-ID<mailman.523.1354740586.29569.python-list@python.org>
In reply to#34297

[Multipart message — attachments visible in raw view] — view raw

On Wed, Dec 5, 2012 at 12:41 PM, Terry Reedy <tjreedy@udel.edu> wrote:

> On 12/5/2012 1:24 PM, Bruno Dupuis wrote:
>
>> On Wed, Dec 05, 2012 at 10:59:26AM -0700, Ian Kelly wrote:
>>>
>>> I think this should even be considered a bug, not just a missing
>>> optimization.  Consider:
>>>
>>
>> This is definitely a bug
>>
>>  globals()['None'] = 42
>>>>>> def f(x):
>>>>>>
>>>>> ...     return None
>>> ...     print(x)
>>> ...
>>>
>>>>  f('test')
>>>>>>
>>>>> 42
>>>
>>
>> This one is pretty scary
>>
>> The difference between `return None` and `return` leads to inconsistency
>> and
>> is in contradiction with the specs, AFAIK. I'm glad we pointed this out.
>>
>
> You did not specify version, but I confirmed in 3.3.0. Please open a
> tracker issue.


It also occurs in 2.6.4

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web