Pull to refresh

Comments 6

Было интересно, но с точки зрения ускорения можно было ужать в одну строчку «Хочешь быстро, используй С», что и было сделано
Не совсем так. В примерах не было ни одной строчки написано на чистом Си. У Cython синтаксис больше python, чем С.
Я не столько о синтаксисе, сколько о потере преимуществ питона перед С, прежде всего о потере динамической типизации.
Cython требует серьезного вмешательства в код, на мой взгляд сопоставимого с написанием отдельных кусков кода на чистом С, что даст сопоставимое ускорение.

Есть два метода оптимизации, которые нужно бы попробовать перед тем, как пытаться делать вещи из статьи:


  1. Для хранения одной записи перейти на именованные кортежи
  2. Если нужно что-то считать, по множеству записей с идентичными полями, то сложить их в Pandas Dataframe.

Что-то мне подсказывает что оно будет столько же, но при этом все лаконично и в пару строчек

На зло всем хейтерам, которые говорят, что python медленный, мы смогли достичь ускорения кода в десятки раз.

Питон создан чтобы управлять, а не для того чтобы работать в поте лица. Пахать должен С++. Отдайте команду numpy, pands, sqlite и они сделают работу быстро и эффективно.


очищать руками память и удалять ненужные элементы по ходу выполнения кода

Я бы скорее это во вредные советы записал. Это всё загромождает код. А с тем что реально получится легко ошибиться.


Например если в dict есть 10000 ключей, мы удаляем оттуда 10000 ключей. Как изменится место занимаемое в памяти?


multiprocessing

Я бы добавил еще асинхронщину.


Разные интересные моменты про производительности
James Powell — Furious & Fast Python 7: Writing Fast Python Code

У меня есть смутное подозрение, что между кодом:


for _ in range(200*100000):
   shop.listGoods.extend([
      DataGoods("телефон", 20000, "RUB"),
      DataGoods("телевизор", 45000, "RUB"),
      DataGoods("тостер", 2000, "RUB")
   ])

… и кодом ...


getGoods = lambda index: {0: ("телефон", 20000, "RUB"), 
                          1: ("телевизор", 45000, "RUB"), 
                          2:("тостер", 2000, "RUB")}.get(index) 
shop.listGoods = [DataGoods(*getGoods(i%3)) for i in range(200*100000)]

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


Замерил на исправленных циклах (200*100000 в первом и 200*100000*3 во втором), результаты следующие:


Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) 
[MSC v.1924 64 bit (AMD64)] on win32

  • Код с extend'ом: в среднем 44 секунды (на основе пяти запусков)
  • Код с lambd'ой: в среднем 57 секунд (на основе пяти запусков)

Веселее оказались результаты с Pypy


Python 3.7.10 (51efa818fd9b, Apr 04 2021, 12:09:32)
[PyPy 7.3.4 with MSC v.1927 64 bit (AMD64)]

  • Код с extend'ом: в среднем 452 секунды (на основе двух запусков, дальше ждать стало лень)
  • Код с lambd'ой: в среднем 23.1 секунда (на основе пяти запусков)

Если кто-то объяснит настолько большую просадку в коде с extend'ом, буду благодарен

Sign up to leave a comment.

Articles