2013-05-05 3 views
0

Я пытаюсь преобразовать свои однострочные perl в pyp. Моя первая попытка была дана мне любезно, как ответ на другой question вПочему pyp (python) однострочный так медленно?

pyp "mm | p if n==0 else (p[:-2] + [(int(x)%12) for x in p[-2:]]) | mm" 

Однако это оказывается удивительно медленно. Если я создать тестовый файл, используя

for j in xrange(50000): 
    print ",".join(str(i) for i in [random.choice(xrange(1000)) for i in xrange(8)]) 

, а затем запустить

time (cat testmedium.txt |~/.local/bin/pyp "mm | p if n==0 else (p[:-2] + [(int(x)%12) for x in p[-2:]]) | mm" > /dev/null) 

Я получаю

real 1m27.889s 
user 1m26.941s 
sys 0m0.688s 

Однако эквивалент в Perl практически мгновенно.

time (cat testmedium.txt |perl -l -a -F',' -p -e'if ($. > 1) { $F[6] %=12; $F[7] %= 12;$_ = join(q{,}, @F[6,7]) }' > /dev/null) 

real 0m0.196s 
user 0m0.192s 
sys 0m0.012s 

Для более крупных тестовых файлов разница еще более драматична.

+8

Переводчики PErl и python делают * не * работают одинаково. То, что быстро с одним может быть худшим подходом в другом. Если вы сказали нам, чего вы пытаетесь достичь, мы, вероятно, могли бы обеспечить быструю питоническую версию. – Bakuriu

+0

@Bakuriu Я думаю, что pyp-код должен делать что-то странное, так как он также использует огромный объем памяти (728 МБ?), Где я ожидаю, что он будет обрабатывать строки в значительной степени на лету.Цель состоит в основном в том, чтобы вводить введенные запятыми численные значения и выводить их в том же формате, за исключением двух чисел в каждой строке, заданной по модулю 12. Связанный вопрос содержит несколько мелких деталей. – marshall

+2

Пробовал ли вы прокомментировать что-то вроде 'pyp" mm | mm "', чтобы проверить, действительно ли это pyp, используя «трубы»? – Bakuriu

ответ

4

Этот код ...

import sys 

for index,line in enumerate(sys.stdin): 
    if index == 0: 
     print line 
    else: 
     values = line.split(',') 
     values[-2:] = [str(int(x)%12) for x in values[-2:]] 
     print ','.join(values) 

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

$ time (cat test.txt | python foo.py > /dev/null) 

real 0m0.363s 
user 0m0.339s 
sys  0m0.032s 

Так что, если вы работаете в проблемы, это, вероятно, неэффективность с чем-то, что делает pyp.

+0

Также создание нового '' '' '' '' '' '', как в 'pyp'-версии, не сильно меняет тайминг, так что это не проблема. – Bakuriu

+0

Я думаю, что это просто ошибка дизайна в pyp. В настоящее время он не подходит для обработки больших файлов. – marshall

0

Это косвенный ответ на ваш вопрос @marshall.

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

Интересно, PyPy может обеспечить более быструю версию PYP поэтому я создал псевдоним для PYP:

alias 'pl=pypy /usr/bin/pyp' 

Затем я запустил эту команду как с PYP и пл

lr | pl "'doc',p, p.replace('e','EEE')+'.xpg' | pp.reverse() | ''.join(p)" | pl "d|u" 

где Л.Р. является псевдоним для ls -R + ls -A только для создания длинного рекурсивного списка во время операции.

Результаты для pyp с использованием Python 2.7.6 и 4.46 секунд для псевдонима pl. Для гораздо большего набора каталогов было 470 и 250 секунд. Python работает на 100% от одного ядра во время этой операции, как и PyPy.

Так что, если у вас есть pypy на вашей системе, возможно, существует существенное увеличение производительности с помощью простого псевдонима.

Смежные вопросы