Какая версия python быстрее? 2.x или 3.х?

python
Теги: #<Tag:0x00007fedb7c47c08>

(ex3me0) #1

Пару недель назад устроили пари на тему: что быстрее, дикт или сет.
Задание было простое: 200к уникальных целых числовых (можно в виде str) значений, длиной 6 символов.

100 итераций:
dict: 30sec
set: 28sec

Использовалась рабочая тачка, с 3.4.3 на борту.

А потом совершенно случайно был запущен тот же код на py2.7.11:

100 итераций:
dict: 12sec
set: 11sec

Думаю в силу подобных причин - грамотные разработчики “не спешат” переходить на соседнюю ветку; но может дело и в лени, отчасти :smiley:

Пример кода, если кому-то интересно, кол-во итераций упразднено до 10ти, т.к. на среднем ноутбуке - уж очень долго ждать)

http://pastebin.com/huVaRLPm


Опрос: Какую версию python Вы используете в автоматизации тестирования?
(Artur Korobeynyk) #2

Если программист пишет на питоне то ему в принципе должно быть наплевать на производительность, так что вы зря спор заводили.
2 работает быстрее 3 исходя как раз из того как питон работает вобще.
Каждый раз когда вы создаете какую-то переменную или вызываете функцию - создается обьект - элементарная частица питона. В питоне всё - это обьект. У обьекта есть какие-то хидеры, например тип обьекта (целое, строковое, плавающее), значение обьекта, ещё какая-то муть. На машинном уровне на заполнение каждого такого хидера уходит время. Питон 3 - это надстройка над 2, он добавил функциональность, учел прошлые недочеты и скорее всего расширил список хидеров использующихся в обьекте (я не нашел полные списки, буду честен, в документации их нету). Тоесть на каждое число созданное вами на машинном коде в третьем питоне будет создано и записано в стек процессора больше значений описывающих хидеры и это займет больше времени.
Улучшения в производительности могут быть разве что в вызове функций из динамических библиотек.
Ну а так для чистой производительности всегда используется один язык - С++. На паскале в принципе можно сделать то же по производительности… теоретически, но его компиляторы не обновлялись уже лет 30, так что результирубщий обьектный код оптимизировать придется вручную.


(rmerkushin) #3

Можно быстрее сделать (без апдейта сета), и разница будет не такая ужасная:

import time
from random import randint


def gen_rand_unique_digits(count=200000, length=6):
    return {str(randint(10**(length-1), 10**length-1)) for _ in range(count)}


if __name__ == "__main__":

    t0 = time.time()
    for x in range(10):
        gen_rand_unique_digits()
    t1 = time.time()

    print("\nRuntime SET:  {0:.2f} Seconds".format(t1 - t0))

C:\Virtualenv\Test\Scripts\python.exe D:/Projects/Test/test.py

Runtime SET: 4.71 Seconds

C:\Virtualenv\2.7.12_Test\Scripts\python.exe D:/Projects/Test/test.py

Runtime SET: 2.66 Seconds

Думаю можно еще шустрее если заюзать numpy, правда там на выходе будут array :slight_smile:
А так, согласен с @arturk, если хочется скорости то нужно юзать C\С++, Rust ну или накрайняк Go )


(ex3me0) #4

А что показывает

len(gen_rand_unique_digits())

Боюсь там никогда не увидеть 200к. Так что нет, не имеет права на жизнь

А что до скорости - легко вещать про си\го\р и т.д., когда у тебя SPAшки на проектах, и гораздо труднее переубедить заказчика переписать 3х-летнего монстра на что-то эфемерно быстрое


(rmerkushin) #5

да, меньше получается, сет съедает одинаковые )
P.S.: Для автотестов я не вижу смысла менять питон на что то другое


(Oleksandr Khotemskyi) #6

Неправильный замер.
Попробуйте через https://docs.python.org/2/library/timeit.html


(rmerkushin) #7

Ну тогда лучше наверное ваще заюзать cProfile или еже с ними https://m.habrahabr.ru/company/mailru/blog/202832/


(Viktor) #8

Я просто оставлю это здесь:


(kixiro) #9

Не согласен про производительность. Есть множество приложений написанных на python, и производительность ой как важна, переписывать все на C++ невозможно, а выбор правильного алгоритма работы приложения очень важен, так что я рад, что появляются такие посты.


(Евгений Бухгаммер) #10

прелесть Питона в том, что если ты пишешь pythonic код, т.е. пользуешься прелестями list comp’ов для генерации списков, или используешь вереницу map filter reduce, то ты априори используешь наиболее оптимизированные операции, лишенные какого-либо оверхеда.

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

  1. а как мне правильно профилировать строку\метод
  2. что в языке является самой тяжелой операцией при работе с множествами
  3. какую версию Питона использовать.

Потому что давайте будет честными: вся мемоизация данных на коленке в принципе доступна за счет кучи крутых библиотек, как например декоратор @numba.jit. И уж если Вы задаетесь вопросом а трансляции кода в С (cython) или байткод для JIT-компиляции (juthon), то это этот тред уж точно не для вас и вы решаете другие задачи.

Питон - высокоуровневый язык, где 99.99\100 разработчиков не должны греть себе голову вопросами скорости в плане того, могут ли они выстрелить себе в ногу. В этом плане хватает базового знания того, какие структуры данных для каких задач вообще созданы. Но если все же очень хочется, то вам по ссылке: