Оптимизация в Python - do's, don'ts и эмпирические правила

Пожалуйста, попробуйте описать вашу проблему в следующий раз вместе с действиями, которые вы предприняли, которые могли вызвать ошибку. Название вашего вопроса грамматически неверно. Я даже не знаю, знаете ли вы, что для запуска приложения на устройстве должен быть запущен симулятор. Так что запустите симулятор из Android Studio, а затем попробуйте запустить приложение. Если это не сработает, вы можете попробовать все решения, упомянутые здесь: https://github.com/facebook/react-native/issues/3091 . Приветствия.

8
задан JV. 31 December 2008 в 20:43
поделиться

8 ответов

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

$ python -m timeit -s "jokes=range(1000000)" "domain=[(0,(len(jokes)*2)-i-1) for i in range(0, len(jokes)*2)]"
10 loops, best of 3: 1.08 sec per loop
$ python -m timeit -s "jokes=range(1000000)" "l=len(jokes);domain=[(0,(l*2)-i-1) for i in range(0, l*2)]"
10 loops, best of 3: 908 msec per loop
$ python -m timeit -s "jokes=range(1000000)" "l=len(jokes*2);domain=[(0,l-i-1) for i in range(0, l)]"
10 loops, best of 3: 813 msec per loop

В то время как ускорение все еще не поразительно, это более значительно (16% и 25% соответственно). Таким образом, так как это больше не делает код сложным, эта простая оптимизация, вероятно, стоит того.

Для рассматривания фактического вопроса..., обычное эмпирическое правило в Python к

  1. Одобрите простой и читаемый код по оптимизации при кодировании.

  2. Представьте свой код (profile / cProfile и pstats Ваши друзья) выяснять то, что необходимо оптимизировать (обычно вещи как жесткие циклы).

  3. Как последнее прибежище повторно реализуйте их как C расширения, который сделан намного легче с инструментами как пирекс и цитон.

Одна вещь не упустить: по сравнению со многими другими языками вызовы функции являются относительно дорогими в Python, который является, почему оптимизация в Вашем примере имела значение даже при том, что len O (1) для списков.

12
ответ дан 5 December 2019 в 07:37
поделиться

Чтение это: Скорость Python / Подсказки по Производительности

Кроме того, в Вашем примере общее время так коротко, что предел погрешности перевесит любое фактическое различие в скорости.

4
ответ дан 5 December 2019 в 07:37
поделиться

Это относится ко всему программированию, не просто Python:

  1. Профиль
  2. Определите узкие места
  3. Оптимизировать

И я даже добавил бы, чтобы не потрудиться делать любой изо что, если у Вас нет проблемы замедления, которая причиняет Вам боль.

И возможно самый важный то, что Модульные тесты помогут Вам во время фактического процесса.

2
ответ дан 5 December 2019 в 07:37
поделиться

На мимоходом связанной ноте, объединяя в цепочку вместе генераторы намного более эффективно, чем объединение в цепочку вместе перечисляет понимания, и часто более интуитивный.

Что касается эмпирических правил разработчика для оптимизации в Python, они совпадают с, они находятся на всех языках.

  1. Не оптимизировать.
  2. (усовершенствованный) Оптимизируют позже.
1
ответ дан 5 December 2019 в 07:37
поделиться

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

Отвечать на Ваш вопрос, хотя, я никогда не заботился бы о вариациях производительности на порядок 5%, если я не делал некоторую сумасшедшую трудную оптимизацию внутреннего цикла на некотором моделировании или чем-то. И в этом случае, Вы могли ускорить это намного больше, не используя диапазон вообще.

1
ответ дан 5 December 2019 в 07:37
поделиться

У нас могут быть некоторые события от людей, которые столкнулись с 'замедлением', какова была проблема и как это было исправлено?

Проблемой был медленный поиск данных в приложении для GUI. Я получил 50x ускорение путем добавления индекса к таблице и был широко провозглашен как герой и спаситель.

0
ответ дан 5 December 2019 в 07:37
поделиться

Самая важная вещь сделать состоит в том, чтобы написать идиоматический, четкий, и красивый код Python. Много общих задач уже найдены в stdlib, таким образом, Вы не должны переписывать более медленную версию. (Я думаю о строковых методах и itertools конкретно здесь.) Делают свободное использование встроенных контейнеров Python, также. dict, например, имел "сопли, оптимизированные" из него, и сказано, что код Python с помощью dicts будет быстрее, чем плоскость C!

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

Относительно пониманий списка: CPython может сделать несколько оптимизации по регулярным циклам аккумулятора. А именно, код операции LIST_APPEND делает добавление к собственной операции списка.

1
ответ дан 5 December 2019 в 07:37
поделиться

У меня есть программа, которая анализирует файлы журналов и создает хранилище данных. Типичный запуск включает около 200 миллионов строк файла журнала и выполняется большую часть дня. Стоит оптимизировать!

Поскольку это синтаксический анализатор, и при этом он анализирует довольно изменчивый, своеобразный и ненадежный текст, существует около 100 регулярных выражений, заранее подготовленных re.compiled () и примененных к каждой из 200 миллионов строк файла журнала. Я был почти уверен, что они были моим узким местом, и размышлял, как исправить эту ситуацию. У меня были идеи: с одной стороны, делать меньше и красивее RE; с другой - больше и проще; вроде того.

Я профилировал с помощью CProfile и смотрел на результат "runnake".

Обработка RE занимала лишь около 10% времени выполнения кода. Это не то!

На самом деле, большая квадратная капля на экране «Runnake» сразу сообщила мне, что около 60% моего времени было потрачено на одно из тех печально известных «однострочных изменений», которые я добавил за один день, исключив непечатаемые символы (которые появляются время от времени, но всегда представляют что-то настолько фальшивое, что меня это действительно не волнует). Это сбивало с толку мой синтаксический анализ и выдачу исключений, о которых я позаботился , потому что это остановило мой день анализа файла журнала.

line = '' .join ([c вместо c в строке, если curses.ascii.isprint (c)])

Итак: эта строка касается каждого байта каждого из этих 200 миллионов строк (а длина строк составляет в среднем пару сотен байт). Неудивительно, что это 60% моего времени выполнения!

Теперь я знаю, что есть более эффективные способы справиться с этим, например str.translate ().Но такие строки редки, и я все равно не забочусь о них, и в конечном итоге они вызывают исключение: теперь я просто ловлю исключение в нужном месте и пропускаю строку. Вуаля! программа работает примерно в 3 раза быстрее, мгновенно!

Таким образом, профилирование

  1. показало примерно за одну секунду, где на самом деле была проблема
  2. , отвлекло мое внимание от ошибочного предположения о том, где была проблема (что могло быть еще более выгодным)
1
ответ дан 5 December 2019 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: