0

Какова польза от базового режима оптимизации Python? (python -O)

16

Проблема: Опция оптимизации в Python -O и ее реальная ценность

В Python существует флаг -O, который позволяет запустить интерпретатор с оптимизациями. Эта опция генерирует "оптимизированный" байт-код (сохраняемый в файлах .pyo), а при запуске дважды она удаляет все строковые документирования (docstrings). Как указано в руководстве пользователя Python:

-O Включить основные оптимизации. Это изменяет расширение имени файлов для скомпилированных (байт-кодовых) файлов с .pyc на .pyo. При запуске дважды приводит к удалению строковых документирований.

У данной опции, по моему мнению, есть две основные функции:

  • Удаление всех операторов assert. Это снижает защиту от поврежденного состояния программы в пользу скорости. Но нужно ли действительно иметь много операторов assert, чтобы это дало заметный эффект? Есть ли у кого-то код, где это может быть полезно (и разумно)?

  • Удаление всех строковых документирований. В каком приложении использование памяти так критично, что это оправдано? Почему бы не вынести все в модули, написанные на C?

Каковы реальные преимущества этой опции? Имеет ли она практическое значение в реальном мире?

5 ответ(ов)

0

Вы почти все правильно поняли: это практически ничего не делает. Вы вряд ли заметите прирост скорости или памяти, если только у вас действительно не будет серьезной нехватки оперативной памяти.

0

Еще одно использование флага -O заключается в том, что значение встроенной переменной __debug__ устанавливается в False.

По сути, в вашем коде могут быть различные "отладочные" пути, например:

if __debug__:
    # выводите всю информацию для отладки, которая вам нравится
    # и еще больше

Когда вы запускаете код с флагом -O, эти участки кода даже не будут включены в байт-код в .pyo файле; это похоже на примитивный аналог #ifdef в C.

Имейте в виду, что строка документации (docstrings) удаляется только когда используется флаг -OO.

0

По поводу удаления утверждений (assert): это стандартная практика в мире C, где многие люди считают, что часть определения ASSERT заключается в том, что они не должны выполняться в коде для продакшн. То, будет ли это иметь значение или нет, зависит не столько от числа утверждений, сколько от того, какую работу выполняют эти утверждения.

Например:

def foo(x):
    assert x in huge_global_computation_to_check_all_possible_x_values()
    # хорошо, можно использовать x...

Конечно, большинство утверждений не требуют такой проверки, но важно помнить, что вы можете делать и такие вещи.

Что касается удаления документирующих строк (docstrings), это кажется чем-то архаичным из более простого времени, хотя, конечно, есть среды с ограниченной памятью, где это может иметь значение.

0

Если у вас есть утверждения (assert) в часто вызываемом коде (например, в внутреннем цикле), то их удаление может значительно повлиять на производительность. Приведу крайний пример:

$ python -c 'import timeit; print(timeit.repeat("assert True"))'
[0.088717937469482422, 0.088625192642211914, 0.088654994964599609]
$ python -O -c 'import timeit; print(timeit.repeat("assert True"))'
[0.029736995697021484, 0.029587030410766602, 0.029623985290527344]

В реальных сценариях экономия времени обычно будет гораздо меньшей.

Удаление строк документации может уменьшить размер вашего кода и, следовательно, ваш рабочий набор.

В большинстве случаев влияние на производительность будет незначительным, но, как всегда, при оптимизации, единственный способ быть уверенным — это провести измерения.

0

Я никогда не встречал убедительной причины для использования флага -O. Я всегда предполагал, что его основное предназначение заключается в том, чтобы, возможно, в будущем были добавлены какие-то значимые оптимизации.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь