Default parameters
Bengt Richter
bokr at oz.net
Fri Dec 19 21:31:04 EST 2003
On Sat, 20 Dec 2003 01:43:00 GMT, Carl Banks <imbosol at aerojockey.invalid> wrote:
>Paul Rubin wrote:
>>
>>
>> Carl Banks <imbosol at aerojockey.invalid> writes:
>>> Consider something like this:
>>>
>>> def func(param=((1,2),(3,4),(5,6),(7,8))):
>>> whatever
>>>
>>> Do you really want to be building a big-ass nested tuple every time
>>> the function is called?
>>
>> Come on, the compiler can easily recognize that that list is constant.
>
>Yes, but that doesn't account for all expensive parameters. What
>about this:
>
> DEFAULT_LIST = ((1,2),(3,4),(5,6),(7,8))
>
> def func(param=DEFAULT_LIST):
> pass
>
>Or this:
>
> import external_module
>
> def func(param=external_modules.create_constant_object()):
> pass
>
>Or how about this:
>
> def func(param={'1': 'A', '2': 'B', '3': 'C', '4': 'D'}):
> pass
>
>
>The compiler couldn't optimize any of the above cases.
For the DEFAULT_LIST (tuple?) and that particular dict literal, why not?
>
>
>>> Python evaluates default args at time of definition mostly for
>>> performance reasons (and maybe so we could simulate closures before we
>>> had real closures). My gut feeling is, moving the evaluation to call
>>> time would be too much of a performance hit to justify it.
>>
>> Python takes so many other performance hits for the sake of
>> convenience and/or clarity that this particular one would be miniscule
>> by comparison.
>
>
>Well, I don't have any data, but my gut feeling is this would be
>somewhat more than "miniscule" performance hit. Seeing how pervasive
>default arguments are, I'm guessing it would be a very significant
>slowdown if default arguments had to be evaluated every call.
>
>But since I have no numbers, I won't say anything more about it.
>
Don't know if I got this right, but
[18:32] /d/Python23/Lib>egrep -c 'def .*=' *py |cut -d: -f 2|sum
Total = 816
[18:32] /d/Python23/Lib>egrep -c 'def ' *py |cut -d: -f 2|sum
Total = 4454
would seem to suggest pervasive ~ 816/4453
or a little less than 20%
Of course that says nothing about which are typically called in hot loops ;-)
But I think it's a bad idea as a default way of operating anyway. You can
always program call-time evaluations explicitly. Maybe som syntactic sugar
could be arranged, but I think I would rather have some sugar for the opposite
instead -- i.e., being able to code a block of preset locals evaluated and bound
locally like current parameter defaults, but not being part of the call signature.
Regards,
Bengt Richter
More information about the Python-list
mailing list