Dalam perl 5, Anda dapat meniru wc -l
menggunakan oneliner:
perl -lnE 'END {say $.}' test.txt
Bagaimana menerapkan fungsi ini di Raku
Jika Anda mencoba menerapkan ini:
raku -e 'say "test.txt".IO.open.lines.elems'
ternyata lambat dan menggunakan banyak memori
Informasi untuk direproduksi:
$ 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
(yang harus mencakup ukuran file). Terima kasih.raku
) masih bagus untuk memilikiraku -v
hasil. Juga, harap pertimbangkan untuk menambahkan output dari waktu saran saya saat ini. Juga, saya mungkin melihat beralih ke'ascii'
decoder akhir pekan ini untuk menghasilkan waktu yang lebih baik.-l
flag untuk perl memperlambat perl secara signifikan dan itu tidak berguna dalam kasus ini. Di komputer saya untuk file dengan panjang garis acak dan sekitar 200 ribu baris, menghapus-l
hasil dalam peningkatan 40%.Jawaban:
Satu opsi yang kemungkinan masih sangat lambat dibandingkan
perl
tetapi patut dibandingkan:The
l
baris perintah pilihan adalah berlebihan.$
adalah skalar status anonim.andthen
menguji apakah lhs didefinisikan, dan jika demikian, tetapkan nilai itu sebagai topik ($_
) dan kemudian mengevaluasi rhnya.END
mirip denganperl
'sEND
. Perhatikan bahwa ia kembaliNil
keandthen
tetapi tidak masalah di sini karena kami menggunakan pernyataanEND
's untuk efek sampingnya.Beberapa hal akan memengaruhi kecepatan kode ini. Beberapa hal yang dapat saya pikirkan:
Kompilasi overhead startup. Mengabaikan modul apa pun yang digunakan,
raku
kompilator Rakudo memiliki overhead startup sekitar sepersepuluh detik pada perangkat keras tipikal dibandingkan dengan yang cukup dapat diabaikanperl
.Gagasan tentang "garis". Dalam
perl
, gagasan standar pemrosesan garis adalah membaca serangkaian byte, yang beberapa di antaranya mewakili akhir baris. Dalamraku
, gagasan default pemrosesan baris adalah membaca string UTF-8, beberapa di antaranya mewakili akhir baris. Dengan demikianperl
hanya menimbulkan overhead membaca dari decoder ASCII (atau Extended ASCII) sedangkanraku
menimbulkan overhead membaca dari decoder UTF-8.Optimalisasi kompiler.
perl
umumnya dioptimalkan ke maks. Itu tidak akan mengejutkan saya jikaperl -lnE 'END {say $.}' test.txt
mengambil keuntungan dari beberapa optimasi pintar. Sebaliknya, pengoptimalan Rakudo masih dalam masa-masa awal.Satu-satunya hal yang saya pikir bisa dilakukan oleh siapa pun tentang poin pertama dan terakhir dari tiga poin yang saya sebutkan di atas adalah menunggu selama N tahun dan / atau berkontribusi pada peningkatan kompiler.
Akan ada cara untuk mengatasi UTF-8-raku secara default. Mungkin sesuatu seperti yang berikut ini sudah bisa dilakukan dan secara signifikan lebih cepat daripada standar raku, setidaknya mengabaikan overhead menggunakan modul yang disebut
foo
:di mana modul
foo
mengalihkan pengodean default untuk file I / O ke ASCII atau apa pun dari pengkodean yang tersedia .Saya belum memeriksa bahwa ini sebenarnya bisa dilakukan di Rakudo saat ini tetapi akan terkejut jika tidak.
sumber