The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)

BartC bc at freeuk.com
Sat Mar 12 12:54:57 EST 2016


On 12/03/2016 16:56, Steven D'Aprano wrote:
> On Sun, 13 Mar 2016 12:42 am, BartC wrote:
>
>> Ad-hoc attributes I don't have as much of a problem with, as they can be
>> handy. But predefined ones also have their points. (For one thing, I
>> know how to implement those efficiently.)
>>
>> However, when you have a function call like this: M.F(), where M is an
>> imported module, then it is very unlikely that the functions in M are
>> going to be created, modified, deleted or replaced while the program
>> runs. [I mean, after the usual process of executing each 'def' statement.]
>
> What do you consider "very unlikely"? And how do you know what people will
> choose to do?

Common sense tells you it is unlikely.

>
>> Why then should it have to suffer the same overheads as looking up
>> arbitrary attributes? And on every single call?
>
> Because they *are* arbitrary attributes of the module. There's only one sort
> of attribute in Python. Python doesn't invent multiple lookup rules for
> attributes-that-are-functions, attributes-that-are-classes,
> attributes-that-are-ints, attributes-that-are-strings, and so on. They are
> all the same.
>
> You gain a simpler implementation,

(Have you tried looking at the CPython sources? I tried last year and 
couldn't head or tail of them. What was the layout of the pyObject 
struct? I couldn't figure it out, the source being such a mess of 
conditional code and macros within macros.

So I wouldn't like to see a complex implementation!)

  a simpler execution model, simpler rules
> for users to learn, and the ability to perform some pretty useful dynamic
> tricks on those occasions where it is useful. For example, monkey-patching
> a module for testing or debugging purposes.

> In languages where functions are different from other values, you have to
> recognise ahead of time "some day, I may need to dynamically replace this
> function with another" and write your code specially to take that into
> account, probably using some sort of "Design Pattern".

No it's very easy. In Python terms:

def f(): return "One"
def g(): return "Two"

h=f

h() returns "One". Later you do h=g, and h() returns "Two". No need for 
f and g themselves to be dynamic. h just needs to be a variable.

The same with modules:

import A
import B

M=A

Now M.F() calls A.F(). Do M=B, and M.B now calls B.F(). No need for 
module names to be dynamic either! Just variables.

>> When you dabble with lots of little things, then they can add up. To the
>> point where an insignificant optimisation can become significant.
>
> Of course. Reduced runtime efficiency is the cost you pay for the
> flexibility gained by significant dynamism. It's a trade-off between
> efficiency, convenience, simplicity, etc. It's quite legitimate for
> language designers to choose to put that trade-off in different places, or
> indeed for the trade-off to change over time.

Maybe the designer(s) of Python didn't know how popular it would get.

Do you think some of the design decisions would be different now?

-- 
Bartc



More information about the Python-list mailing list