Pada server multi-core, gunakan paralel GNU untuk menghitung baris file secara paralel. Setelah setiap jumlah baris file dicetak, bc menjumlahkan semua jumlah baris.
find . -name '*.txt' | parallel 'wc -l {}' 2>/dev/null | paste -sd+ - | bc
Untuk menghemat ruang, Anda bahkan dapat menyimpan semua file terkompresi. Baris berikut membuka kompresi setiap file dan menghitung barisnya secara paralel, lalu menjumlahkan semua hitungan.
find . -name '*.xz' | parallel 'xzcat {} | wc -l' 2>/dev/null | paste -sd+ - | bc
Sesuai pengujian saya, saya dapat memverifikasi bahwa Spark-Shell (berdasarkan Scala) jauh lebih cepat daripada alat lain (GREP, SED, AWK, PERL, WC). Berikut adalah hasil pengujian yang saya jalankan pada file yang memiliki 23782409 baris
time grep -c $ my_file.txt;
nyata 0m44.96pengguna 0m41.59ssys 0m3.09s
time wc -l my_file.txt;
nyata 0m37.57pengguna 0m33.48ssys 0m3.97s
time sed -n '$=' my_file.txt;
nyata 0m38.22pengguna 0m28.05ssys 0m10.14s
time perl -ne 'END { $_=$.;if(!/^[0-9]+$/){$_=0;};print "$_" }' my_file.txt
;
nyata 0m23.38pengguna 0m20.19ssys 0m3.11s
time awk 'END { print NR }' my_file.txt;
nyata 0m19.90pengguna 0m16.76ssys 0m3.12s
spark-shell
import org.joda.time._
val t_start = DateTime.now()
sc.textFile("file://my_file.txt").count()
val t_end = DateTime.now()
new Period(t_start, t_end).toStandardSeconds()
res1:org.joda.time.Seconds =PT15S
Faktor kecepatan pembatas Anda adalah kecepatan I/O perangkat penyimpanan Anda, jadi mengubah antara baris baru/program penghitungan pola tidak akan membantu, karena perbedaan kecepatan eksekusi antara program tersebut cenderung ditekan dengan cara disk/penyimpanan yang lebih lambat/ apa pun yang Anda miliki.
Tetapi jika Anda memiliki file yang sama yang disalin ke seluruh disk/perangkat, atau file tersebut didistribusikan di antara disk tersebut, Anda pasti dapat melakukan operasi secara paralel. Saya tidak tahu secara spesifik tentang Hadoop ini, tetapi dengan asumsi Anda dapat membaca file 10 GB dari 4 lokasi berbeda, Anda dapat menjalankan 4 proses penghitungan baris yang berbeda, masing-masing dalam satu bagian file, dan menjumlahkan hasilnya:
$ dd bs=4k count=655360 if=/path/to/copy/on/disk/1/file | wc -l &
$ dd bs=4k skip=655360 count=655360 if=/path/to/copy/on/disk/2/file | wc -l &
$ dd bs=4k skip=1310720 count=655360 if=/path/to/copy/on/disk/3/file | wc -l &
$ dd bs=4k skip=1966080 if=/path/to/copy/on/disk/4/file | wc -l &
Perhatikan &
di setiap baris perintah, sehingga semua akan berjalan secara paralel; dd
berfungsi seperti cat
di sini, tetapi izinkan kami untuk menentukan berapa banyak byte yang akan dibaca (count * bs
byte) dan berapa banyak yang harus dilewati di awal input (skip * bs
byte). Ini bekerja dalam blok, oleh karena itu, kebutuhan untuk menentukan bs
sebagai ukuran blok. Dalam contoh ini, saya telah mempartisi file 10Gb dalam 4 potongan yang sama 4Kb * 655360 =2684354560 byte =2,5GB, satu diberikan untuk setiap pekerjaan, Anda mungkin ingin menyiapkan skrip untuk melakukannya untuk Anda berdasarkan ukuran file dan jumlah pekerjaan paralel yang akan Anda jalankan. Anda juga perlu menjumlahkan hasil eksekusi, yang belum saya lakukan karena kurangnya kemampuan skrip shell.
Jika sistem file Anda cukup pintar untuk membagi file besar di antara banyak perangkat, seperti RAID atau sistem file terdistribusi atau semacamnya, dan secara otomatis memparalelkan permintaan I/O yang dapat dilumpuhkan, Anda dapat melakukan pemisahan seperti itu, menjalankan banyak pekerjaan paralel, tetapi menggunakan jalur file yang sama, dan Anda mungkin masih mendapatkan beberapa peningkatan kecepatan.
EDIT:Gagasan lain yang terpikir oleh saya adalah, jika baris di dalam file memiliki ukuran yang sama, Anda bisa mendapatkan jumlah baris yang tepat dengan membagi ukuran file dengan ukuran baris, keduanya dalam byte. Anda dapat melakukannya hampir secara instan dalam satu pekerjaan. Jika Anda memiliki ukuran rata-rata dan tidak terlalu peduli dengan jumlah garis, tetapi menginginkan perkiraan, Anda dapat melakukan operasi yang sama ini dan mendapatkan hasil yang memuaskan jauh lebih cepat daripada operasi sebenarnya.
Coba:sed -n '$=' filename
Kucing juga tidak diperlukan:wc -l filename
sudah cukup dengan cara Anda saat ini.