On 3/5/2018 7:12 AM, Kirill Balunov wrote:
Hi,

At the moment, in order to slightly speed up the function in Python, free
variables are passed as local variables to the function, thereby getting
rid of extra look ups. For example, for the following function, I
especially do not use list comprehension) and therefore maybe it's not the
best example:

     def func(numb):
         res = []
         for i in range(numb):
             res.append(int(i) + float(i))
         return res

You can get rid of additional look ups, in the following ways:


# 1. By passing through local variable's default values

     def func_local_1(numb, _int = int, _float = float, _range = range):

You are not required to mangle the names.

def func_local_1(numb, int = int, float = float, range = range):
...

     res = []
     for i in _range(numb):
         res.append(_int(i) + _float(i))
     return res


# 2. Through importing them into the function scope

     def func_local_2(numb):
         from builtins import int, float, range
         res = []
         for i in range(numb):
             res.append(int(i) + float(i))
         return res


# 3. With the help of various types of closures, version 1

     def func_closure_1(numb):
         _int = int
         _float = float
         _range = range
         def inner(numb):
             res = []
             for i in _range(numb):
                 res.append(_int(i) + _float(i))
             return res
         return inner(numb)


# 4. With the help of various types of closures, version 2

     def func_closure_2(numb):
         from builtins import int, float, range
         def inner(numb):
             res = []
             for i in range(numb):
                 res.append(int(i) + float(i))
             return res
         return inner(numb)

Option 1 allows you to achieve the maximum result for both small and a
large `numb` values. Option 2 yields a significant overhead, when it is
required to call function many times with a small number of iterations. For
option 3 and 4, notes are the same, but since they are implemented through
closures they give additional small overhead. In case of big `numb` (many
iterations, many look ups) these options give a gain of ~10%.

Option 1 and 3 I do not like because:
  - syntax highlighting stops working

Only because you unnecessarily mangle the names.

  - the signature function is greatly distorted
  - additional typing (especially with type annotations)

I like options 2 and 4, but they yield a significant overhead, for a small
number of iterations.

Actually, I have the following question:

1. Is there any other way to make the variable local to the function?
      a. When you compile (define) a function...
      b. Inject into an already existing function through decorator...(is it
possible?)

p.s.:

I had the following idea, maybe it was already discussed, the possibility
of setting _static_ variables for functions, with the following syntax:

     def func(numb):
         static int, float, range
         res = []
         for i in range(numb):
             res.append(int(i) + float(i))
         return res

Where identifiers for `static` should correspond to free variables for a
function, they must be defined at compile time (like for default arguments)
and can not be changed inside the function scope.

With kind regards,
-gdg



--
Terry Jan Reedy

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

Reply via email to