Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #98341 > unrolled thread
| Started by | "wangq@travelsky.com" <wangq@travelsky.com> |
|---|---|
| First post | 2015-11-06 10:33 +0800 |
| Last post | 2015-11-13 09:52 +1100 |
| Articles | 20 on this page of 110 — 24 participants |
Back to article view | Back to comp.lang.python
Question about math.pi is mutable "wangq@travelsky.com" <wangq@travelsky.com> - 2015-11-06 10:33 +0800
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-06 12:30 +0000
Re: Question about math.pi is mutable Lorenzo Sutton <lorenzofsutton@gmail.com> - 2015-11-06 17:12 +0100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-06 19:30 +0000
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-07 06:40 +1100
Re: Question about math.pi is mutable Christian Gollwitzer <auriocus@gmx.de> - 2015-11-06 20:59 +0100
Re: Question about math.pi is mutable Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-06 23:19 +0100
Re: Question about math.pi is mutable Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-07 00:48 +0100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-07 13:00 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-07 14:43 +1100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 11:23 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-07 22:35 +1100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 11:57 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-07 23:15 +1100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 13:00 +0000
Re: Question about math.pi is mutable Laura Creighton <lac@openend.se> - 2015-11-07 15:09 +0100
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-07 16:23 +0200
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-07 16:28 +0200
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 15:01 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-07 19:46 +0200
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-08 14:07 +1100
Re: Question about math.pi is mutable Random832 <random832@fastmail.com> - 2015-11-08 01:29 -0500
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-08 13:59 +1100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-08 10:40 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 13:02 +0200
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 11:19 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 13:50 +0200
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 12:39 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 14:43 +0200
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 13:42 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 16:33 +0200
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 02:11 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-09 11:58 +1100
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-08 23:28 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-09 11:35 +1100
Re: Question about math.pi is mutable Michael Torrie <torriem@gmail.com> - 2015-11-08 08:59 -0700
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 17:54 +0000
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 05:01 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 18:58 +0000
Re: Question about math.pi is mutable Ian Kelly <ian.g.kelly@gmail.com> - 2015-11-08 12:51 -0700
Re: Question about math.pi is mutable Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-11-08 18:13 -0500
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 23:54 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 11:00 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-09 00:11 +0000
Re: Question about math.pi is mutable Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-11-09 08:18 -0500
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 11:04 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 11:26 +1100
Re: Question about math.pi is mutable Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-11-09 21:29 +1300
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 11:36 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 11:50 +1100
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 11:56 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 12:04 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-09 22:22 +1100
Re: Question about math.pi is mutable Random832 <random832@fastmail.com> - 2015-11-09 10:32 -0500
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 06:45 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-10 13:37 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 17:10 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-10 22:34 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-10 13:26 +0000
Re: Question about math.pi is mutable Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-11-11 18:38 +1100
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-11 10:30 +0200
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-11 22:20 +1100
Re: Question about math.pi is mutable Terry Reedy <tjreedy@udel.edu> - 2015-11-10 03:30 -0500
Re: Question about math.pi is mutable Laura Creighton <lac@openend.se> - 2015-11-10 11:33 +0100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 23:14 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-11 12:10 +1100
Re: Question about math.pi is mutable Laura Creighton <lac@openend.se> - 2015-11-09 21:07 +0100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 10:21 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-09 16:54 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 06:52 +1100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 08:00 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 22:35 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-09 09:54 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-09 13:23 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-09 12:22 +0000
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-09 23:36 +1100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-08 22:30 +1100
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 12:24 +0000
Re: Question about math.pi is mutable Grant Edwards <invalid@invalid.invalid> - 2015-11-07 16:16 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-07 20:00 +0200
Re: Question about math.pi is mutable Grant Edwards <invalid@invalid.invalid> - 2015-11-08 03:31 +0000
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 09:45 +0200
Re: Question about math.pi is mutable Christian Gollwitzer <auriocus@gmx.de> - 2015-11-08 09:00 +0100
Re: Question about math.pi is mutable Paul Rubin <no.email@nospam.invalid> - 2015-11-08 00:08 -0800
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 11:49 +0200
Re: Question about math.pi is mutable Grant Edwards <invalid@invalid.invalid> - 2015-11-09 14:49 +0000
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 15:19 +0000
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-08 14:50 +1100
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 11:44 +0200
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-08 22:11 +1100
Re: Question about math.pi is mutable Marko Rauhamaa <marko@pacujo.net> - 2015-11-08 13:25 +0200
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-08 11:06 +0000
Re: Question about math.pi is mutable Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-09 15:49 +0100
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-10 10:29 +1100
Re: Question about math.pi is mutable Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-10 11:03 +0100
Re: Question about math.pi is mutable Michael Torrie <torriem@gmail.com> - 2015-11-13 20:11 -0700
Re: Question about math.pi is mutable Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-14 16:02 +0100
Re: Question about math.pi is mutable Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-06 23:26 +0100
Re: Question about math.pi is mutable Terry Reedy <tjreedy@udel.edu> - 2015-11-06 20:49 -0500
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-07 13:06 +1100
Re: Question about math.pi is mutable Bartc <bc@freeuk.com> - 2015-11-07 23:02 +0000
Re: Question about math.pi is mutable Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-11-07 23:27 +0000
Re: Question about math.pi is mutable Ben Finney <ben+python@benfinney.id.au> - 2015-11-08 10:32 +1100
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-08 10:52 +1100
Re: Question about math.pi is mutable Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-12 21:40 +0100
Re: Question about math.pi is mutable Steven D'Aprano <steve@pearwood.info> - 2015-11-13 09:04 +1100
Re: Question about math.pi is mutable Denis McMahon <denismfmcmahon@gmail.com> - 2015-11-13 09:19 +0000
Re: Question about math.pi is mutable Larry Hudson <orgnut@yahoo.com> - 2015-11-13 18:30 -0800
Re: Question about math.pi is mutable BartC <bc@freeuk.com> - 2015-11-12 22:19 +0000
Re: Question about math.pi is mutable Chris Angelico <rosuav@gmail.com> - 2015-11-13 09:52 +1100
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2015-11-08 18:13 -0500 |
| Message-ID | <mailman.152.1447024427.16136.python-list@python.org> |
| In reply to | #98472 |
On Sun, 8 Nov 2015 18:58:36 +0000, BartC <bc@freeuk.com> declaimed the
following:
>But then, you say that additional attributes, potentially millions of
>different ones, can be invented at runtime. Although I don't see how it
>can remove names that are part of the source code: if "A.B" is in the
>file, then surely "A" and "B" always have to be present in some table or
>other.
-=-=-=-=- module.py
class Something(object):
def __init__(self):
pass
-=-=-=-=- main.py
import module
module.remote = module.Something()
nonremote = module.remote
nonremote.x = "Looky here"
print module.remote.x
module.remote.x = 3.14
print nonremote.x
module.remote = None
print nonremote.x
print module.remote.x
Where do you propose to "tableize" remote, nonremote, and x. "remote"
doesn't exist inside module.py until one executes main.py -- so it can't be
optimized to when the compiler parses module.py (creating, in most cases a
bytecode module.pyc). You can't optimize it to main.py since (not shown in
my example) there may be another imported package that also imports module
and references module.remote -- and could even replace it with a new object
(in which case nonremote is still associated with the old object, not the
new one)
The effort needed to trace all usages in order to make your optimized
tables is effectively the same effort needed to run the program in the
first place.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2015-11-08 23:54 +0000 |
| Message-ID | <n1on71$san$1@dont-email.me> |
| In reply to | #98484 |
On 08/11/2015 23:13, Dennis Lee Bieber wrote:
> On Sun, 8 Nov 2015 18:58:36 +0000, BartC <bc@freeuk.com> declaimed the
> following:
>
>> But then, you say that additional attributes, potentially millions of
>> different ones, can be invented at runtime. Although I don't see how it
>> can remove names that are part of the source code: if "A.B" is in the
>> file, then surely "A" and "B" always have to be present in some table or
>> other.
>
> -=-=-=-=- module.py
>
> class Something(object):
> def __init__(self):
> pass
>
> -=-=-=-=- main.py
>
> import module
>
> module.remote = module.Something()
> nonremote = module.remote
> nonremote.x = "Looky here"
> print module.remote.x
> module.remote.x = 3.14
> print nonremote.x
> module.remote = None
> print nonremote.x
> print module.remote.x
Is this typical Python code? Creating global objects in other modules
(or writing all over essential data structures in a library module).
If most code is going to be more sensible, then I mentioned an approach
in my other post just over an hour ago. The idea there was to optimise
attribute lookups when code is written with more restraint. (So defining
functions, classes and attributes within classes in a boring manner.)
> Where do you propose to "tableize" remote, nonremote, and x. "remote"
> doesn't exist inside module.py until one executes main.py -- so it can't be
In your example, only attributes "remote" and "x" exist. But the tables
for those will be empty as it is not practical to add in runtime-created
attributes. Then, a conventional lookup would be needed.
> optimized to when the compiler parses module.py (creating, in most cases a
> bytecode module.pyc). You can't optimize it to main.py since (not shown in
> my example) there may be another imported package that also imports module
> and references module.remote -- and could even replace it with a new object
> (in which case nonremote is still associated with the old object, not the
> new one)
The tables would reflect the static layout of the attributes as defined
in the source code. Since the source code is finite, the tables will be
also (unlike runtime when a billion attributes could be created).
If your module.py code is tweaked like this:
class Something(object):
x=0
def __init__(self):
pass
remote=0
Then 'x' and 'remote' become static attributes that can now added to
tables for fast lookup. Although this does require that these two are
effectively 'declared'.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-09 11:00 +1100 |
| Message-ID | <mailman.153.1447027222.16136.python-list@python.org> |
| In reply to | #98485 |
BartC <bc@freeuk.com> writes: > Is this typical Python code? Creating global objects in other modules > (or writing all over essential data structures in a library module). Not “creating global objects”, but changing the referent of a name in some other module. Yes, that's quite a common technique. Does that surprise you? If it surprises you, hopefully you can learn some more Python with this new knowledge. -- \ “We can't depend for the long run on distinguishing one | `\ bitstream from another in order to figure out which rules | _o__) apply.” —Eben Moglen, _Anarchism Triumphant_, 1999 | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2015-11-09 00:11 +0000 |
| Message-ID | <n1oo88$vj1$1@dont-email.me> |
| In reply to | #98486 |
On 09/11/2015 00:00, Ben Finney wrote: > BartC <bc@freeuk.com> writes: > >> Is this typical Python code? Creating global objects in other modules >> (or writing all over essential data structures in a library module). > > Not “creating global objects”, but changing the referent of a name in > some other module. Yes, that's quite a common technique. Does that > surprise you? Changing the referent (I assume that just means assigning to it or updating the associated value) wouldn't be a problem. Provided the name was defined in that other module, because then it is a name the compiler would know about. (And, more importantly, someone reading the code in that module would know about.) > If it surprises you, hopefully you can learn some more Python with this > new knowledge. Yes, that it's more of a crazy language than it looks at first; I can write a simple module like this: pass which looks like an empty module, yet for all I know will end up contain hundreds of variables by the time it's run. (I normally use my own language, that I call 'dynamic', but compared with Python it might as well be carved in stone!) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2015-11-09 08:18 -0500 |
| Message-ID | <mailman.173.1447075122.16136.python-list@python.org> |
| In reply to | #98488 |
On Mon, 9 Nov 2015 00:11:58 +0000, BartC <bc@freeuk.com> declaimed the
following:
>Yes, that it's more of a crazy language than it looks at first; I can
>write a simple module like this:
>
>pass
>
>which looks like an empty module, yet for all I know will end up contain
>hundreds of variables by the time it's run.
>
Yet, for those situations where one needs shared "global" objects,
having a bucket module just for this purpose may be the solution (though
I'd personally think the design of the application could be improved to
make it less arbitrary).
It is a capability of the language, and anything that removes that
feature risks breaking existing applications. It might make it into Python
4000...
Also remember that compiled module files (PYC) don't know in what
environment they will be used. Your restrictions may force the system to
recompile EVERY Python module referenced whenever the main program file
changes, even if the modules have had no changes and the previous PYC file
is available.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-09 11:04 +1100 |
| Message-ID | <mailman.154.1447027474.16136.python-list@python.org> |
| In reply to | #98485 |
On Mon, Nov 9, 2015 at 11:00 AM, Ben Finney <ben+python@benfinney.id.au> wrote: > BartC <bc@freeuk.com> writes: > >> Is this typical Python code? Creating global objects in other modules >> (or writing all over essential data structures in a library module). > > Not “creating global objects”, but changing the referent of a name in > some other module. Yes, that's quite a common technique. Does that > surprise you? Changing the referent of an existing name, definitely. Creating new names, not so much. You don't often reach into another module and create a new attribute. Testing/mocking is a completely separate consideration (eg you can inject a shadow for a built-in name); if some Python implementation has a fast path that gets defeated by "module.int = MagicInt", and it causes the tests to run slower, so be it. Other than that, I can't think of many cases (actually, can't think of any, off hand) where you inject names into other modules. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-09 11:26 +1100 |
| Message-ID | <mailman.155.1447028787.16136.python-list@python.org> |
| In reply to | #98485 |
Chris Angelico <rosuav@gmail.com> writes: > Testing/mocking is a completely separate consideration (eg you can > inject a shadow for a built-in name) Not for the purpose of making compiler optimisations, as BartC is advocating. The compiler definitely should not treat “is this code part of a test suite?” as a relevant criterion for deciding what optimisation. We should certainly not have a compiler that makes needless difference to code behaviour under test conditions versus non-test conditions. So, since those optimisations would cripple perfectly normal test code, that should be sufficient to quash the desire to make them. -- \ “If you define cowardice as running away at the first sign of | `\ danger, screaming and tripping and begging for mercy, then yes, | _o__) Mr. Brave man, I guess I'm a coward.” —Jack Handey | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-11-09 21:29 +1300 |
| Message-ID | <dab3rkFi9vaU1@mid.individual.net> |
| In reply to | #98490 |
Ben Finney wrote: > We > should certainly not have a compiler that makes needless difference to > code behaviour under test conditions versus non-test conditions. Indeed. Volkswagen tried a version of that recently, and it didn't end well... -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-09 11:36 +1100 |
| Message-ID | <mailman.156.1447029391.16136.python-list@python.org> |
| In reply to | #98485 |
On Mon, Nov 9, 2015 at 11:26 AM, Ben Finney <ben+python@benfinney.id.au> wrote: > Chris Angelico <rosuav@gmail.com> writes: > >> Testing/mocking is a completely separate consideration (eg you can >> inject a shadow for a built-in name) > > Not for the purpose of making compiler optimisations, as BartC is > advocating. > > The compiler definitely should not treat “is this code part of a test > suite?” as a relevant criterion for deciding what optimisation. We > should certainly not have a compiler that makes needless difference to > code behaviour under test conditions versus non-test conditions. > > So, since those optimisations would cripple perfectly normal test code, > that should be sufficient to quash the desire to make them. But I distinguish between crippling *performance* and crippling *functionality*. If the compiler optimizations are defeated, so the test suite falls back on the slow path, that means your tests run slower. Unless you're testing the optimizer itself, this shouldn't be a problem. This is broadly the same kinds of optimizations that Fat Python is playing with. Effectively, what it says is "I think that 'len' is this object", and then it guards the fast path with a quick check for validity. So if you go in and change something, the result is that the slow path gets used instead. The question then is whether it's worth the optimization effort. Will the slow path be penalized more than the fast path gains? Will the code complexity introduce more bugs? The same consideration comes up in JavaScript/ECMAScript (where object attributes can also be created dynamically), and I know some interpreters have been written to do a slot-based lookup, so the concept does have at least some merit. Personally, I'm dubious about the value of this in CPython; but I'm willing to be persuaded. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-09 11:50 +1100 |
| Message-ID | <mailman.158.1447030266.16136.python-list@python.org> |
| In reply to | #98485 |
Chris Angelico <rosuav@gmail.com> writes: > On Mon, Nov 9, 2015 at 11:26 AM, Ben Finney <ben+python@benfinney.id.au> wrote: > > Chris Angelico <rosuav@gmail.com> writes: > > > >> Testing/mocking is a completely separate consideration (eg you can > >> inject a shadow for a built-in name) > > > > Not for the purpose of making compiler optimisations, as BartC is > > advocating. […] since those optimisations would cripple perfectly > > normal test code, that should be sufficient to quash the desire to > > make them. > > But I distinguish between crippling *performance* and crippling > *functionality*. If the compiler optimizations are defeated, so the > test suite falls back on the slow path, that means your tests run > slower. Unless you're testing the optimizer itself, this shouldn't be > a problem. You misunderstand me. I'm not saying the optimisations would be crippled. I am saying that, in order to achieve those optimisations, the *test code* would be crippled. I am pointing out that the assumption necessary for the optimisation BartC is advocating – the optimisation of module attributes to be immutable after compilation – depends on crippling the *functionality* needed for many uses, including test code uses. Since the compiler should not be in the position of deciding whether code is test code or not, it cannot use that criterion to decide whether to enable or disable the optimisation. So either the optimisation should never be enabled (my perference), or test code will unwittingly be crippled by the assumptions needed for that optimisation. -- \ “We are all agreed that your theory is crazy. The question that | `\ divides us is whether it is crazy enough to have a chance of | _o__) being correct.” —Niels Bohr (to Wolfgang Pauli), 1958 | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-09 11:56 +1100 |
| Message-ID | <mailman.159.1447030606.16136.python-list@python.org> |
| In reply to | #98485 |
On Mon, Nov 9, 2015 at 11:50 AM, Ben Finney <ben+python@benfinney.id.au> wrote: > You misunderstand me. I'm not saying the optimisations would be > crippled. I am saying that, in order to achieve those optimisations, the > *test code* would be crippled. > > I am pointing out that the assumption necessary for the optimisation > BartC is advocating – the optimisation of module attributes to be > immutable after compilation – depends on crippling the *functionality* > needed for many uses, including test code uses. > > Since the compiler should not be in the position of deciding whether > code is test code or not, it cannot use that criterion to decide whether > to enable or disable the optimisation. > > So either the optimisation should never be enabled (my perference), or > test code will unwittingly be crippled by the assumptions needed for > that optimisation. Hmm, then I was misunderstanding what BartC was advocating. I didn't think it would *fail* in the presence of dynamic attributes, but merely *perform suboptimally* (and presumably worse than current CPython). If it does indeed require crippling the functionality, then I agree, this is a bad idea. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-09 12:04 +1100 |
| Message-ID | <mailman.160.1447031104.16136.python-list@python.org> |
| In reply to | #98485 |
Chris Angelico <rosuav@gmail.com> writes: > Hmm, then I was misunderstanding what BartC was advocating. I didn't > think it would *fail* in the presence of dynamic attributes, but > merely *perform suboptimally* (and presumably worse than current > CPython). There isn't a way for the compiler to *know*, in all cases, whether module attributes will be updated during the lifetime of the program (short of, as pointed out elsewhere, running the entire program under all possible conditions). So the optimisation can't be applied by the compiler without risking breaking perfectly valid code. That is enough, IMO, to kill the proposal; if the compiler could break *any* valid code, it's no longer a Python compiler. -- \ “If [a technology company] has confidence in their future | `\ ability to innovate, the importance they place on protecting | _o__) their past innovations really should decline.” —Gary Barnett | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-09 22:22 +1100 |
| Message-ID | <564081e7$0$1592$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #98498 |
On Mon, 9 Nov 2015 12:04 pm, Ben Finney wrote:
> There isn't a way for the compiler to *know*, in all cases, whether
> module attributes will be updated during the lifetime of the program
> (short of, as pointed out elsewhere, running the entire program under
> all possible conditions).
>
> So the optimisation can't be applied by the compiler without risking
> breaking perfectly valid code.
It's not 1980 any more, compiler technology has come a long way since the
Dragon Book. In the words of Steve Yegge, describing the attitudes of C++
developers who insist that no other language (and especially dynamic
languages) can be sufficiently fast:
"And so, you know, their whole argument is based on these fallacious, you
know, sort of almost pseudo-religious... and often it's the case that
they're actually based on things that used to be true, but they're not
really true anymore"
http://steve-yegge.blogspot.com.au/2008/05/dynamic-languages-strike-back.html
The compiler doesn't need to decide in advance whether or not the module
attributes have been changed. It can decide that at runtime, just before
actually looking up the attribute. In pseudo-code:
if attribute might have changed:
use the slow path just like today
else:
use the optimized fast path
The PyPy FAQs suggest that PyPy is capable of fast, optimized attribute
access in this fashion, using a guard to ensure the fast path is taken only
when “this class attribute was not modified”. I'm not a compiler expert,
but I would expect that this sort of technology could be adapted to do the
same for module attributes.
http://doc.pypy.org/en/latest/faq.html
Such optimizations don't come for free: PyPy has taken a lot of development
effort, and some funding from the EU. And PyPy is more memory-hungry than
CPython. But that's just the same old trade-off that programmers have been
doing since time immemorial: you can save time, or you can save space, but
you can rarely save both together.
Other dynamic languages also have proven fast implementations: for decades,
Lisp (dynamic) and Fortran (static) were the two fastest languages around.
If Lisp has fallen behind, it is not because it is dynamic, but because
nobody is working on optimizing it. What was optimal in 1975 may not be
optimal on today's hardware.
Javascript and PHP also have extremely fast versions. Javascript's V8
compiler is actually two compilers in one, and it automatically swaps over
to the optimizing compiler when it is appropriate:
http://jayconrod.com/posts/54/a-tour-of-v8-crankshaft-the-optimizing-compiler
When Crankshaft's assumptions are violated, the compiler automatically swaps
back to running the unoptimized code.
Facebook took a different approach with HipHop, using a JIT language
translator that takes PHP and outputs compiled C++ code:
https://www.facebook.com/notes/facebook-engineering/hiphop-for-php-move-fast/280583813919
HipHop is perhaps not the best example, as it does give up some of the most
dynamic features of PHP, such as eval. The post above isn't clear whether
using such features is prohibited, or merely falls back on the slow,
regular PHP interpreter when you use them.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2015-11-09 10:32 -0500 |
| Message-ID | <mailman.181.1447083172.16136.python-list@python.org> |
| In reply to | #98512 |
Steven D'Aprano <steve@pearwood.info> writes:
> The compiler doesn't need to decide in advance whether or not the module
> attributes have been changed. It can decide that at runtime, just before
> actually looking up the attribute. In pseudo-code:
>
> if attribute might have changed:
> use the slow path just like today
> else:
> use the optimized fast path
if attribute might have changed:
check if attribute really did change
if it didn't:
reset means of determining if it might have changed
goto the optimized fast path
else:
use the slow path and/or maybe make a new fast path
else:
use the optimized fast path
And what if your optimization depends on _two_ things that might change?
Do you create one really fast path and two sort of fast paths?
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-10 06:45 +1100 |
| Message-ID | <mailman.186.1447098364.16136.python-list@python.org> |
| In reply to | #98512 |
Steven D'Aprano <steve@pearwood.info> writes: > The compiler doesn't need to decide in advance whether or not the > module attributes have been changed. It can decide that at runtime, > just before actually looking up the attribute. In pseudo-code: > > if attribute might have changed: > use the slow path just like today > else: > use the optimized fast path As you have pointed out earlier, the “attribute might have changed” condition is set by *any* non-trivial code — notably, a function call, though that doesn't exhaust the ways of setting that condition. So the remaining space of code that is safe for the proposed optimisation is trivially small. Why bother with such optimisations, if the only code that can benefit is *already* small and simple? I'm not asking you (Steven) to defend the proposal, I'm pointing out that the “problem” being addressed is essentially the dynamism of Python. The proposal is misguided. -- \ “Truth would quickly cease to become stranger than fiction, | `\ once we got as used to it.” —Henry L. Mencken | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-10 13:37 +1100 |
| Message-ID | <56415873$0$1614$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #98549 |
On Tue, 10 Nov 2015 06:45 am, Ben Finney wrote: > Steven D'Aprano <steve@pearwood.info> writes: > >> The compiler doesn't need to decide in advance whether or not the >> module attributes have been changed. It can decide that at runtime, >> just before actually looking up the attribute. In pseudo-code: >> >> if attribute might have changed: >> use the slow path just like today >> else: >> use the optimized fast path > > As you have pointed out earlier, the “attribute might have changed” > condition is set by *any* non-trivial code — notably, a function > call, though that doesn't exhaust the ways of setting that condition. Ben, I fear that you are not paying attention to me :-) The compiler doesn't need to decide *in advance* whether the attribute might have changed. It knows whether it has changed or not *at runtime*. I'm not a compiler writer, but I pretend to be one on Usenet *wink* so don't take this as gospel. Treat it as a simple-minded illustration of what sort of thing a JIT compiler could do. It's one thing to say that *in principle* any function might modify or shadow builtins. That's true, because we don't know what's inside the function. But the compiler knows, because it actually executes the code inside the function and can see what happens when it does. It doesn't have to predict in advance whether or not calling `func(x)` shadows the builtin `len` function, *it can see for itself* whether it did or not. At compile time, `func(x)` might do anything. But at runtime, we know exactly what it did, because it just did it. Imagine that the compiler keeps track of whether or not builtins has been modified. Think of it as a simple "dirty" flag that says "yes, builtins is still pristine" or "no, something may have shadowed or modified the builtins". That's fairly straight-forward: builtins is a dict, and the compiler can tell whether or not __setitem__ etc has been called on that dict. Likewise, it can keep track of whether or not a global has been created that shadows builtins: some of that can be done statically, at compile-time, but most of it needs to be done dynamically, at runtime. If the flag is set, the compiler knows that the optimization is unsafe and it has to follow the standard name lookup, and you lose nothing: the standard Python semantics are still followed. But if the flag is clear, the compiler knows that nothing has shadowed or modified builtins, and a whole class of optimizations are safe. It can replace a call to (say) len(x) with a fast jump, avoiding an unnecessary name lookup in globals, and another unnecessary name lookup in builtins. Or it might even inline the call to len. Since *most* code doesn't play tricks with builtins, the overhead of tracking these changes pays off *most* of the time -- and when it doesn't, the penalty is very small. Depending on how smart the compiler is, there are all sorts of things it can do. The state of the art (not bleeding edge) for JIT compilers is pretty smart these days. CPython is a simple-minded, dumb compiler, and that's the way Guido likes it (its the reference implementation, not the fastest or most memory efficient implementation). But PyPy can approach the speed of statically optimized C, at least sometimes, and certainly can beat CPython by an order of magnitude. Likewise Javascript's V8 compiler. > So the remaining space of code that is safe for the proposed > optimisation is trivially small. Why bother with such optimisations, if > the only code that can benefit is *already* small and simple? That is absolutely not correct. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-10 17:10 +1100 |
| Message-ID | <mailman.198.1447135830.16136.python-list@python.org> |
| In reply to | #98570 |
Steven D'Aprano <steve@pearwood.info> writes: > Ben, I fear that you are not paying attention to me :-) Possibly, though I also think there's miscommunication in this thread. You speak of “compile time” and “run time”. You also speak of what the compiler can do, at run time. I am a Bear of Little Brain, but: Isn't anything that the *compiler* does, by definition done at *compile* time? The run-time behaviour of the program is, of course, *affected* by what the compiler has done in the past. But the compiler acts only at compile time, and its compile-time behaviour can't be determined by what's happening at run time. If that's not true, I fear we're not talking about the same things. > At compile time, `func(x)` might do anything. But at runtime, we know > exactly what it did, because it just did it. Sure. All my statements about compile-time optimisations are those that can be applied at compile time (which I intend to be synonymous with “when the compiler is doing its job”), and so can't be informed by what happens at run time. If the proposal is to make optimisations that must be informed by the run-time state of the running program, we're surely talking about not just the compiler any more. No? -- \ “Any sufficiently advanced bug is indistinguishable from a | `\ feature.” —Rich Kulawiec | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-10 22:34 +1100 |
| Message-ID | <5641d63a$0$1603$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #98575 |
On Tue, 10 Nov 2015 05:10 pm, Ben Finney wrote:
> Steven D'Aprano <steve@pearwood.info> writes:
>
>> Ben, I fear that you are not paying attention to me :-)
>
> Possibly, though I also think there's miscommunication in this thread.
>
> You speak of “compile time” and “run time”. You also speak of what the
> compiler can do, at run time.
>
> I am a Bear of Little Brain, but: Isn't anything that the *compiler*
> does, by definition done at *compile* time?
In a manner of speaking, yes, of course. But you've missed the critical
issue: when is compile time?
If you're like most people, you probably are thinking about an execution
model where the compiler analyses the source code statically, using nothing
but what can be seen in the source code, then hands over some sort of
compiled byte code to be run by an interpreter or machine code that is
executed by the CPU. The compiler and interpreter are completely distinct.
If so, you're stuck with an obsolete model of computation, like somebody
trying to understand modern chemistry based on the "planetary orbit" model
of the atom.
So when is compile time? Of course, in some languages (like C, or Pascal)
compilation occurs as a distinct stage before you can run the code. But
that's not necessarily true for all compilers. "Just In Time" compilers
operate while the program is running, compiling code just before it is
executed. The distinction between compiler and interpreter is gone, or at
least weakened.
Python -- yes, even CPython -- has a runtime compiler. When you import a
module, it is compiled (if needed) just before the import. Likewise, when
you call the `compile`, `eval` or `exec` built-ins, the compiler operates.
I'm not calling this a JIT compiler, because the simple-minded compilation
performed by `compile` etc doesn't use any run-time information. It just
statically compiles the code to byte-code.
But the fact that it happens *at runtime* is significant, because in
principle there is a lot more information available to the compiler, if it
were intelligent enough to make use of it. For example, suppose you execute
this Python snippet:
result = x + 2
At static compile time, looking just at the source, you may not know what
value x is, or even whether or not x actually exists, so you're forced to
go through the standard Python semantics to determine what the result is:
py> from dis import dis
py> dis("result = x + 1")
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (1)
6 BINARY_ADD
7 STORE_NAME 1 (result)
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
But a JIT compiler gets to compile code right before that line is due to
execute. By the time the JIT compiler gets to see that line of code, it can
already know whether or not name "x" exists, and if so, which namespace it
is in. It knows what value "x" has. The compiler can choose what byte code,
or even machine code, to generate, using information available just before
that code is needed.
Suppose it knows that "x" is bound to an float. Then it can cast the int 1
to the machine floating point double 1.0 and generate code that adds that
to a float. That's likely to be tens of times faster than the BINARY_ADD
op-code, which has to do a whole lot of type-checking, method calling, and
creating and disposing of objects to add the two values.
Only if "x" is unknown, or if it is some type that doesn't have a convenient
optimization, does the JIT compiler generate the standard (but unoptimized)
BINARY_ADD op-code.
Provided that, on average, the book-keeping needed by the JIT compiler is
outweighed by the gains, the whole process counts as a win.
Now, CPython doesn't include a JIT compiler. But PyPy does, and it is much
more sophisticated than anything I could explain. I'm not the only one:
https://glyph.twistedmatrix.com/2012/02/this-isnt-how-pypy-works-but-it-might.html
If you remember Psycho, that might help. Psycho (according to its creator)
isn't a "true" JIT compiler, but it's close enough. Psycho would generate
machine code -- actual low level code running in the CPU or FPU, not byte
code -- for certain Python operations, plus guard code that ensured the
machine code was only called when it was safe to do so. So this is long
proven technology.
More about JIT compilation on Wikipedia:
https://en.wikipedia.org/wiki/Just-in-time_compilation
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2015-11-10 13:26 +0000 |
| Message-ID | <n1sr6n$d6f$1@dont-email.me> |
| In reply to | #98589 |
On 10/11/2015 11:34, Steven D'Aprano wrote:
> On Tue, 10 Nov 2015 05:10 pm, Ben Finney wrote:
>
>> I am a Bear of Little Brain, but: Isn't anything that the *compiler*
>> does, by definition done at *compile* time?
>
> In a manner of speaking, yes, of course. But you've missed the critical
> issue: when is compile time?
>
> If you're like most people, you probably are thinking about an execution
> model where the compiler analyses the source code statically, using nothing
> but what can be seen in the source code, then hands over some sort of
> compiled byte code to be run by an interpreter or machine code that is
> executed by the CPU. The compiler and interpreter are completely distinct.
Does the Python language specify how it is to be compiled and executed?
If not, then you can use any interpretation you like, provided the
program gives the expected results.
That includes using a static compilation pass that generates byte-code,
even if it is only done immediately before running the main module, or
just before performing an import operation on another.
> If so, you're stuck with an obsolete model of computation, like somebody
> trying to understand modern chemistry based on the "planetary orbit" model
> of the atom.
>
> So when is compile time? Of course, in some languages (like C, or Pascal)
> compilation occurs as a distinct stage before you can run the code. But
> that's not necessarily true for all compilers.
C can also be interpreted from source as you go along, although it can
be very difficult (but probably not as difficult as implementing PyPy).
Anything is possible. But the chances are that if you are running
CPython, then it will probably include a discrete byte-code compiler.
> execute
> this Python snippet:
>
> result = x + 2
>
> At static compile time, looking just at the source, you may not know what
> value x is, or even whether or not x actually exists, so you're forced to
> go through the standard Python semantics to determine what the result is:
>
> py> from dis import dis
> py> dis("result = x + 1")
> 1 0 LOAD_NAME 0 (x)
> 3 LOAD_CONST 0 (1)
> 6 BINARY_ADD
> 7 STORE_NAME 1 (result)
> 10 LOAD_CONST 1 (None)
> 13 RETURN_VALUE
>
>
> But a JIT compiler gets to compile code right before that line is due to
> execute. By the time the JIT compiler gets to see that line of code, it can
> already know whether or not name "x" exists, and if so, which namespace it
> is in. It knows what value "x" has.
How does it do that? How is the 'x+1' even stored in the machine?
Suppose the preceding lines are:
if random+bit()==1:
x=920.5
else:
x=[8,5,4,9,1,7,6,3,2]
or:
if some_condition: del x
it will probably know as much about x as the static compiler does! And a
static compiler can still do a surprising bit of analysis, such as
transforming the the first if-statement above, followed by your return
statement, into:
if random_bit()==1:
return 922.5
else:
raise_error()
But we're trying to find ways of avoiding a dictionary lookup, ie a
LOAD_GLOBAL or LOAD_NAME. If static analysis of the entire source can
yield fixed tables of such names as 'x', even if subject to runtime
alterations, then why not do that if it means possible faster access.
> More about JIT compilation on Wikipedia:
>
> https://en.wikipedia.org/wiki/Just-in-time_compilation
JIT covers a lot including straightforward translation of byte-code for
a statically language, into native code.
In a language like Python, it's rather more elaborate.
And PyPy, as you hinted, is complelely different. I don't think it even
attempts to JIT compile your example, it JIT compiles some repeatedly
executed pathways in a program some way removed from the Python code or
even its interpreter.
Or something like that... Whatever it is, it's more like magic. But what
I started discussing here are ways of making a regular Python
interpreter more efficient. I think that with projects such as PyPy,
people are less interested with speeding up CPython, for one thing
because it is not going to speed things up by ten times, so there seems
little point.
--
BartC
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-11-11 18:38 +1100 |
| Message-ID | <5642f079$0$1527$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #98597 |
On Wednesday 11 November 2015 00:26, BartC wrote: > Does the Python language specify how it is to be compiled and executed? Not in so many words, but there are limitations on what you can do based on the specified semantics of Python. But so long as you meet those semantics, you can implement them any reasonable way you like: - CPython uses one specific implementation written in C; - PyPy uses a powerful tracing JIT compiler written in an intermediate language RPython; - IronPython uses the .Net CLR virtual machine; - Jython uses the Java virtual machine; - there was an experimental version of Python using the Parrot virtual machine; etc. Those implementations will naturally perform differently. For example, I believe that IronPython *generally* is faster than CPython, with some exceptions. > If not, then you can use any interpretation you like, provided the > program gives the expected results. Precisely. > That includes using a static compilation pass that generates byte-code, > even if it is only done immediately before running the main module, or > just before performing an import operation on another. That's what CPython already does. > Anything is possible. But the chances are that if you are running > CPython, then it will probably include a discrete byte-code compiler. Since compile, eval and exec are Python built-ins, if it doesn't include a byte-code compiler, it isn't Python. It's just a subset of Python. >> execute this Python snippet: >> >> result = x + 2 [...] >> But a JIT compiler gets to compile code right before that line is due to >> execute. By the time the JIT compiler gets to see that line of code, it >> can already know whether or not name "x" exists, and if so, which >> namespace it is in. It knows what value "x" has. > > How does it do that? How is the 'x+1' even stored in the machine? That depends entirely on the implementation of the compiler. > Suppose the preceding lines are: > > if random+bit()==1: > x=920.5 > else: > x=[8,5,4,9,1,7,6,3,2] > > or: > > if some_condition: del x > > it will probably know as much about x as the static compiler does! Not at all. The difference is, having called rand_bit() and tested whether it is 1, the compiler takes a branch: - it binds 920.5 to x - or it binds [8, 5, 4, ...] to x The compiler knows which branch it just took, *because it just took it*. If it doesn't know which branch it just took, it isn't a JIT compiler! It's just a classic, old-fashioned interpreter with no smarts. So, having just bound some value to x, the compiler knows that x is a float (or a list), and can optimize the next instruction, which is "x + 1". CPython can't do that, because it doesn't have the infrastructure to perform the necessary book-keeping. And it probably never will do that, because Guido likes the fact that CPython is simple enough for him to understand. He's happy for PyPy and other third-party implementations to do the clever stuff. -- Steven
[toc] | [prev] | [next] | [standalone]
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
Back to top | Article view | comp.lang.python
csiph-web