В Perl 5 вы можете эмулировать, wc -l
используя oneliner:
perl -lnE 'END {say $.}' test.txt
Как реализовать эту функциональность на Raku
Если вы попытаетесь реализовать это:
raku -e 'say "test.txt".IO.open.lines.elems'
он оказывается медленным и использует много памяти
Информация для воспроизведения:
$ wget http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.zip
$ unzip "1500000 Sales Records.zip"
$ mv "1500000 Sales Records.csv" part.txt
$ for i in `seq 1 10`; do cat part.txt >> test.txt ; done
$ du -sh test.txt
1.8G test.txt
$ time wc -l test.txt
15000000 test.txt
real 0m0,350s
user 0m0,143s
sys 0m0,205s
$ time perl -lnE 'END { say $. }' test.txt
15000001
real 0m1,981s
user 0m1,719s
sys 0m0,256s
$ time raku -e 'say "test.txt".IO.open.lines.elems'
15000001
real 2m51,852s
user 0m25,129s
sys 0m6,378s
# Using swap (maximum uses 2.2G swap):
# Before `raku -e ''`
$ free -m
total used free shared buff/cache available
Mem: 15009 1695 12604 107 708 12917
Swap: 7583 0 7583
# After `raku -e ''`
$ free -m
total used free shared buff/cache available
Mem: 15009 752 13923 72 332 13899
Swap: 7583 779 6804
# Swap not used
$ time raku -ne '++$ andthen END .say' test.txt
15000001
real 1m44,906s
user 2m14,165s
sys 0m0,653s
$ raku -v
This is Rakudo version 2019.11 built on MoarVM version 2019.11
implementing Perl 6.d.
wc
(который должен включать размер файла). Спасибо.raku
), было бы хорошо иметьraku -v
вывод. Также, пожалуйста, рассмотрите возможность добавления выходных данных моего текущего предложения. Кроме того, я могу рассмотреть переход на'ascii'
декодер позже в эти выходные, чтобы лучше провести время.-l
флаг для Perl значительно замедляет Perl, и в этом случае он бесполезен. На моей машине для файла со случайной длиной строки и около 200 тыс. Строк удаление-l
приводит к улучшению на 40%.Ответы:
Один вариант, который все еще может быть довольно медленным по сравнению с тем,
perl
но его стоит сравнить:Опция
l
командной строки является избыточной.$
скаляр анонимного состояния.andthen
проверяет, что определены его lhs, и если да, устанавливает это значение как topic ($_
), а затем оценивает его rhs.END
похож наperl
'sEND
. Обратите внимание, что он возвращаетсяNil
к,andthen
но это не имеет значения, потому что мы используемEND
оператор s для его побочного эффекта.Несколько вещей будут влиять на скорость этого кода. Некоторые вещи, которые я могу придумать:
Затраты на запуск компилятора. Игнорируя любые используемые модули,
raku
компилятор Rakudo имеет накладные расходы при запуске примерно на одну десятую секунды на типичном оборудовании по сравнению с довольно незначительным дляperl
.Понятие "линия". В
perl
стандартном понятии обработки строки по умолчанию читается серия байтов, некоторые из которых представляют конец строки. Вraku
стандартном понятии обработки строки по умолчанию читается строка UTF-8, часть которой представляет конец строки. Таким образом,perl
возникают только издержки чтения декодера ASCII (или расширенного ASCII), тогдаraku
как накладные расходы чтения декодера UTF-8.Оптимизация компилятора.
perl
как правило, оптимизирован до макс. Меня не удивит, еслиperl -lnE 'END {say $.}' test.txt
воспользоваться некоторыми умными оптимизациями. В отличие от этого, работа по оптимизации Rakudo все еще находится в ее ранних днях, условно говоря.Единственное, что, я думаю, каждый может сделать с первым и последним из трех упомянутых выше моментов, - это подождать N лет и / или внести свой вклад в улучшение компилятора.
Будет способ обойти UTF-8 по умолчанию у raku. Возможно, что-то вроде следующего уже выполнимо и значительно быстрее, чем стандартное значение raku, по крайней мере игнорируя издержки использования модуля под названием
foo
:где модуль
foo
переключает кодировку по умолчанию для файлового ввода / вывода на ASCII или любую другую из доступных кодировок .Я не проверял, что это реально выполнимо в текущем Rakudo, но был бы удивлен, если бы не было.
источник