Переопределяются ли внутренние функции каждый раз, когда вызывается их родительская функция? - PullRequest
0 голосов
/ 03 апреля 2020

Я знаю, что функции в Python являются гражданами 1-го класса, что означает, что они являются объектами класса function, аналогично тому, как 5 является объектом класса int. Это означает, что в какой-то момент их жизни вызывается конструктор. Для большинства функций я ожидаю, что это произойдет, когда они будут определены (так как большинство функций, по-видимому, определяются только один раз), так что мы платим только одну цену за конструкцию, независимо от того, сколько раз мы ее используем.

Но как насчет вложенные функции? Они переопределяются каждый раз, когда вызывается их родитель. Значит ли это, что мы каждый раз перестраиваем объект? Если да, разве это не очень неэффективно? Разве частный метод (если исходная функция является методом) или другая функция не будет намного более эффективным? Я игнорирую ограничивающие аргументы в пользу вложения для этого обсуждения.

Я провожу простой эксперимент, который, кажется, поддерживает мой вышеупомянутый аргумент, поскольку выпуск внутренней функции медленнее:

import time

def f(x, y):
    def defined_inside(x, y):
        return x + y
    return defined_inside(x, y)

def defined_outside(x, y):
    return x + y

def g(x, y):
    return defined_outside(x, y)

start = time.time()
for i in range(10000000):
    _ = f(3, 4)
end = time.time()

print("Using inner function it took {} seconds".format(end - start))

start = time.time()
for i in range(10000000):
    _ = g(3, 4)
end = time.time()

print("Using outer function it took {} seconds".format(end - start))

Результаты:

Using inner function it took 2.494696855545044 seconds
Using outer function it took 1.8862690925598145 seconds

Бонусный вопрос: Если вышеприведенное верно, как ситуация относится к компилируемым языкам, таким как Scala? Я превратился в огромное удовольствие от вложенности и функций более высокого порядка, было бы ужасно, если трюк настолько неэффективен, как кажется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...