Скорость генератора в питоне 3

Я просматриваю ссылку на генераторы, которую кто-то разместил. Вначале он сравнивает две приведенные ниже функции. На своей установке он показал увеличение скорости на 5% с генератором.

Я использую Windows XP, Python 3.1.1 и не могу воспроизвести результаты. Я продолжаю показывать «старый способ» (logs1) как немного более быстрый при тестировании с предоставленными журналами и до 1 ГБ дублированных данных.

Может ли кто-нибудь помочь мне понять, что происходит по-другому?

Спасибо!

def logs1():
    wwwlog = open("big-access-log")
    total = 0
    for line in wwwlog:
        bytestr = line.rsplit(None,1)[1]
        if bytestr != '-':
            total += int(bytestr)
    return total

def logs2():
    wwwlog = open("big-access-log")
    bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog)
    getbytes      = (int(x) for x in bytecolumn if x != '-')
    return sum(getbytes)

*edit, интервалы перепутаны при копировании/вставке


person Will    schedule 08.03.2010    source источник
comment
Мне кажется, что эти две функции по существу одинаковы. Ни в том, ни в другом случае вы не создаете огромный список, вместо которого вы могли бы использовать генератор. Так что я не удивлен, что они бегают примерно с одинаковой скоростью.   -  person MatrixFrog    schedule 08.03.2010
comment
Это имеет смысл, мне просто любопытно, почему он получает увеличение скорости на 5%, а я постоянно вижу снижение примерно на 1%.   -  person Will    schedule 08.03.2010


Ответы (3)


Что бы это ни стоило, основная цель сравнения скорости в презентации состояла в том, чтобы указать, что использование генераторов не приводит к огромным потерям производительности. Многие программисты, впервые увидев генераторы, могут начать задаваться вопросом о скрытых затратах. Например, происходит ли за кулисами всевозможная причудливая магия? Заставит ли использование этой функции мою программу работать в два раза медленнее?

В общем, это не так. Пример предназначен для демонстрации того, что решение генератора может работать практически с той же скоростью, а в некоторых случаях и чуть быстрее (хотя это зависит от ситуации, версии Python и т. д.). Если вы наблюдаете огромные различия в производительности между двумя версиями, то это стоит изучить.

person David Beazley    schedule 08.03.2010

На слайдах Дэвида Бизли, на которые вы ссылаетесь, он утверждает, что все тесты проводились с «Python 2.5.1 в OS X 10.4.11», а вы говорите, что выполняете тесты с Python 3.1 в Windows XP. Итак, поймите, что вы проводите сравнение яблок с апельсинами. Я подозреваю, что из двух переменных версия Python имеет гораздо большее значение.

Python 3 отличается от Python 2. Многое изменилось внутри (даже в ветке Python 2). Это включает в себя оптимизацию производительности, а также снижение производительности (см., например, недавняя запись в собственном блоге Бизли о вводе-выводе в Python 3). По этой причине на странице Советы по производительности Python прямо указано:

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

Я должен упомянуть, что одна из областей, в которой вы можете рассчитывать на помощь генераторов, заключается в снижении потребления памяти, а не потребления ЦП. Если у вас есть большой объем данных, где вы вычисляете или извлекаете что-то из каждой отдельной части, и вам не нужны данные после этого, генераторы будут сиять. Дополнительные сведения см. в разделе понимание генератора.

person gotgenes    schedule 08.03.2010
comment
Понятно, я так и подозревал, поэтому я написал, что использую python3. Опять же, мне было любопытно, что происходит по-другому. - person Will; 08.03.2010
comment
Если вам действительно интересно, попробуйте запустить временные тесты с установкой Python 2.6; если это не дает вам разницы, попробуйте установить Python 2.5 и посмотрите, не сможете ли вы воспроизвести результаты Бизли. Или вы можете быть ленивым, как я, и просто написать Python-dev. - person gotgenes; 08.03.2010

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

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

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

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

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

Надеюсь это поможет

person inspectorG4dget    schedule 08.03.2010
comment
Кроме того, второй алгоритм вызывает функцию суммы в конце, в отличие от первого алгоритма, который просто продолжает добавлять соответствующие целые числа по мере их обнаружения. Я думаю, что это не имеет значения, потому что sum(), вероятно, не помещает все значения в память, а затем добавляет их. Вероятно, он добавляет их по мере выполнения итерации, как и другой код. - person MatrixFrog; 08.03.2010