Подтвердить что ты не робот

Почему моя версия Python медленнее, чем моя версия Perl?

Я был парком Perl более 10 лет, но друг убедил меня попробовать Python и сказал мне, насколько он быстрее, чем Perl. Так что для пинков я портировал приложение, написанное в Perl на Python, и обнаружил, что он работает примерно на 3 раза медленнее. Первоначально мой друг сказал мне, что я, должно быть, сделал это неправильно, поэтому я переписал и реорганизовал, пока я не смог переписать и не рефакторировать больше и... он все еще намного медленнее. Поэтому я сделал простой тест:

i = 0
j = 0

while (i < 100000000):
    i = i + 1
    j = j + 1

print j

$time python python.py
100000000

real 0m48.100s
пользователя 0m45.633s
sys 0m0.043s

my $i = 0;
my $j = 0;

while ($i < 100000000) {
    ++$i; # also tested $i = $i + 1 to be fair, same result
    ++$j;
}

print $j;

$time perl perl.pl
100000000

real 0m24.757s
пользователя 0m22.341s
sys 0m0.029s

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

4b9b3361

Ответ 1

Ответ на выбор nit заключается в том, что вы должны сравнить его с идиоматическим Python:

  • Исходный код занимает 34 секунды на моей машине.
  • A for loop (ответ FlorianH) с += и xrange() принимает 21.
  • Помещение всего объекта в функцию уменьшает его до 9 секунд!
    Это намного быстрее, чем Perl (15 секунд на моей машине)!
    Объяснение: Локальные локали Python намного быстрее, чем глобальные.
    (Для справедливости я также пробовал функцию в Perl - без изменений)
  • Избавление от переменной j уменьшило ее до 8 секунд:

    print sum(1 for i in xrange(100000000))

У Python есть странное свойство, что более быстрый код более высокого уровня имеет тенденцию быть самым быстрым: -)

Но реальный ответ заключается в том, что ваш "микро-бенчмарк" не имеет смысла. Реальный вопрос о скорости языка: какова производительность среднего реального приложения? Чтобы это знать, вы должны учитывать:

  • Типичное сочетание операций в сложном коде. Ваш код не содержит никаких структур данных, вызовов функций или операций ООП.

  • Достаточно большая база кода, чтобы ощущать эффекты кеша - многие оптимизаторы интерпретатора используют торговую память для скорости, которая не измеряется справедливо ни одним крошечным эталоном.

  • Оптимизация возможности: после вы пишете свой код, если он не достаточно быстрый, насколько быстрее вы можете легко это сделать?

    например. насколько трудно разгружать тяжелый подъем на эффективные C-либрики?

Тесты PyPy и Octane являются хорошие примеры того, как выглядят реалистичные языковые тесты скорости.

Если вы хотите поговорить с хрустом числа, Python IS на удивление популярен среди ученых. Они любят его для простого псевдоматного синтаксиса и короткой кривой обучения, но также для отличной библиотеки numpy для хруста массива и простоты обертывания другого существующего кода C.

И затем есть Psyco JIT, который, вероятно, запустит ваш пример с игрушкой менее 1 секунды, но я не могу проверить его сейчас потому что он работает только на 32-битном x86.
EDIT: В настоящее время пропустите Psyco и используйте PyPy, где кросс-платформа активно улучшает JIT.

Ответ 2

Все это микро-бенчмаркинг может стать немного глупым!

Например, просто переключение на for в Python и Perl обеспечивает высокую скорость. Первоначальный пример Perl был бы вдвое быстрее, если бы использовался for:

my $j = 0;

for my $i (1..100000000) {
    ++$j;
}

print $j;


И я могу немного сбрить с этим:

++$j for 1..100000000;
print $j;


И, становясь еще глуже, мы можем получить его до 1 секунды здесь; -)

print {STDOUT} (1..10000000)[-1];

/I3az/

ref: используется Perl 5.10.1.

Ответ 3

Python не особенно быстро работает с числовыми вычислениями, и я уверен, что он медленнее, чем perl, когда дело доходит до обработки текста.

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

Update

Хорошо. Я просто создал большой файл (1 ГБ) со случайными данными в нем (в основном ascii) и разбил его на строки равной длины. Это должно было имитировать файл журнала.

Затем я запускал простые программы perl и python, которые ищут файл строки за строкой для существующего шаблона.

С Python 2.6.2 результаты были

real    0m18.364s
user    0m9.209s
sys 0m0.956s

и с Perl 5.10.0

real    0m17.639s
user    0m5.692s
sys 0m0.844s

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

import re
regexp = re.compile("p06c")

def search():
    with open("/home/arif/f") as f:
        for i in f:
            if regexp.search(i):
                print "Found : %s"%i

search()

и

sub search() {
  open FOO,"/home/arif/f" or die $!;
  while (<FOO>) {
    print "Found : $_\n" if /p06c/o;
  }
}

search();

Результаты довольно близки, и их настройка так или иначе не сильно изменяет результаты. Я не знаю, является ли это истинным эталоном, но я думаю, что я бы поискал файлы журналов на двух языках, поэтому я исправляю относительные характеристики.

Спасибо Крису.

Ответ 4

Python работает очень быстро, если вы используете правильный синтаксис языка python. Он примерно описан как pythonic".

Если вы реструктурируете свой код, как это, он будет работать как минимум в два раза быстрее (ну, это на моей машине):

j = 0
for i in range(10000000):
    j = j + 1
print j

Всякий раз, когда вы используете время на python, вы должны проверить, можете ли вы также использовать "для X в диапазоне()".

Ответ 5

В OP, в Python этот фрагмент кода:

j = 0
for i in range(10000000):
    j = j + 1
print j

совпадает с

print range(10000001)[-1]

который на моей машине

$ time python test.py
10000000

real    0m1.138s
user    0m0.761s
sys     0m0.357s

пробегает приблизительно 1 с. range() (или xrange) является внутренним для Python и "внутренне", он уже может генерировать последовательность чисел для вас. Поэтому вам не нужно создавать свои собственные итерации, используя собственный цикл. Теперь вы идете и находите эквивалент Perl, который может работать в течение 1 с для получения того же результата.

Ответ 6

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

Чтобы повысить производительность, вы должны использовать локальное распределение, например, создание функции. Интерпретатор Python хранит локальные переменные в массиве с гораздо более быстрым доступом.
Однако следует отметить, что это деталь реализации CPython; Я подозреваю, что IronPython, например, приведет к совершенно другому результату.

Наконец, для получения дополнительной информации по этой теме я предлагаю вам интересное эссе из GvR, посвященное оптимизации в Python: Шаблоны Python - Анекдот оптимизации.

Ответ 7

python медленнее, чем perl. Это может быть быстрее развиваться, но оно не выполняется быстрее. Здесь приведен один критерий http://xodian.net/serendipity/index.php?/archives/27-Benchmark-PHP-vs.-Python-vs.-Perl-vs.-Ruby.html -edit- страшный тест, но это, по крайней мере, реальный бенчмарк с числами, а не догадываться. Для плохого нет источника или теста другого, а затем цикла.

Ответ 8

Я не обновляюсь на всех с Python, но моя первая идея об этом контроле была разницей между числами Perl и Python. В Perl у нас есть числа. Они не являются объектами, и их точность ограничена размерами, налагаемыми архитектурой. В Python у нас есть объекты с произвольной точностью. Для небольших чисел (те, которые соответствуют 32-битным), я ожидаю, что Perl будет быстрее. Если мы перейдем к целочисленному размеру архитектуры, Perl script даже не будет работать без какой-либо модификации.

Я вижу похожие результаты для исходного теста на моем MacBook Air (32-разрядный), используя Perl 5.10.1, который я скомпилировал сам и Python 2.5.1, который пришел с Leopard:

Однако я добавил произвольную точность в программу Perl с bignum

 use bignum;

Теперь мне интересно, закончится ли версия Perl.:) Я опубликую некоторые результаты, когда закончится, но похоже, что это будет различие в величине порядка.

Некоторые из вас, возможно, видели мой вопрос о Какие пять вещей вы ненавидите в своем любимом языке?. Perl-номера по умолчанию - одна из вещей, которые я ненавижу. Я никогда не должен думать об этом, и это не должно быть медленным. В Perl я проигрываю на обоих. Обратите внимание, однако, что если бы мне нужна числовая обработка в Perl, я мог бы использовать PDL.

Ответ 9

Python действительно намного медленнее, чем Perl?

Посмотрите на Компьютерные игры Benchmarks Game - "Сравните производительность ≈30 языков программирования, используя ≈12 ошибочных тестов и ≈1100 программ".

Это всего лишь крошечные тестовые программы, но они по-прежнему намного больше, чем фрагмент кода, который вы приурочили -

http://shootout.alioth.debian.org/u32/python.php