Генераторы и итераторы не всегда быстрее обычного for`а

1849 1

Среди коллег разработчиков на python бытует мнение что генераторы и итераторы быстрее, чем перебор for`ом
Но это не всегда так. 
Вот пример:


def sum_times():
    ch = ['bad', 'good']
    data_list = [(random.choice(ch), 10) for i in range(100000)]
 
    time_start = datetime.datetime.now()
    res = 0
    for i in data_list:
        if i[0] == 'good':
            res += i[1]
    print(f'for_list result: {res} \tElapsed: {datetime.datetime.now() - time_start}\n')
 
    time_start = datetime.datetime.now()
    res = sum([i[1] for i in data_list if i[0] == 'good'])
    print(f'gen_list result: {res} \tElapsed: {datetime.datetime.now() - time_start}\n')
 
    time_start = datetime.datetime.now()
    res = sum((i[1] for i in data_list if i[0] == 'good'))
    print(f'gen_tuple result: {res} \tElapsed: {datetime.datetime.now() - time_start}\n')
 
    time_start = datetime.datetime.now()
    res = sum([i[1] for i in filter(lambda x: x[0] == 'good', data_list)])
    print(f'filter_list result: {res} \tElapsed: {datetime.datetime.now() - time_start}')

Ну и на выходе получаем:
sum_times()
for_list result: 500750 	Elapsed: 0:00:00.006345

gen_list result: 500750 	Elapsed: 0:00:00.005756

gen_tuple result: 500750 	Elapsed: 0:00:00.006345

filter_list result: 500750 	Elapsed: 0:00:00.010971
Как видим генераторное списочное выражение в данном случае быстрее всего.
А вот генератор по скорости работает как обычный перебор for`ом. 
Ну а использование filter полный провал.

P.S. Прежде чем использовать тот или иной способ, стоит попробовать, так как в разных случаях бывает по разному.

Комментарии

14 декабря 2023 г. 14:50 owlman
Для python 3.10.7:
for_list result: 496750 Elapsed: 0:00:00.004048
gen_list result: 496750 Elapsed: 0:00:00.004138
gen_tuple result: 496750 Elapsed: 0:00:00.003463
filter_list result: 496750 Elapsed: 0:00:00.005275

Контактные данные

 Россия, г. Москва