Saya memiliki FILE_A yang memiliki lebih dari 300.000 baris dan FILE_B yang memiliki lebih dari 30 juta baris. Saya membuat skrip Bash yang membuat setiap baris dalam FILE_A berakhir di FILE_B dan menulis hasil grep ke file baru.
Seluruh proses ini memakan waktu lebih dari 5 jam.
Bagaimana saya dapat meningkatkan kinerja skrip saya?
Saya menggunakan grep -F -m 1
sebagai perintah grep. FILE_A terlihat seperti ini:
123456789
123455321
dan FILE_B seperti ini:
123456789,123456789,730025400149993,
123455321,123455321,730025400126097,
Jadi dengan Bash saya memiliki while
loop yang mengambil baris berikutnya di FILE_A dan melihatnya di FILE_B. Ketika pola ditemukan di FILE_B, saya menulisnya ke file result.txt.
while read -r line; do
grep -F -m1 $line 30MFile
done < 300KFile
algorithms
performance
perl
bash
rogerio_marcio
sumber
sumber
Berikut adalah jawaban Perl untuk anak cucu. Saya secara rutin melakukan ini untuk mencocokkan 1M baris ke 30-35M baris. Diperlukan sekitar 10 detik untuk menyelesaikannya.
Pertama, hash hingga FILE_A:
Lalu, jika file besar Anda dibatasi dan tahu kolom mana yang harus dicari, periksa keberadaan kunci hash saat Anda menjalankan FILE_B, yang jauh, lebih cepat daripada memeriksa persamaan atau pencocokan ekspresi reguler:
Jika file target Anda yang lebih besar tidak dapat diurai dengan baik, maka skrip ini kehilangan nilainya karena begitu banyak kecepatannya berasal dari tidak harus menyalakan mesin ekspresi reguler .
sumber
Jika Anda tidak keberatan dengan pemrograman yang lebih terlibat, pertimbangkan untuk menggunakan pohon suffix (atau varian).
Anda dapat melakukan preproses
FILE_B
menggunakan algoritma Ukkonen dalam waktu linier. Kemudian, Anda kueri setiap baris dalamFILE_A
waktu linier dalam panjang garis dan mendapatkan semua nomor baris yang cocok (mungkin perlu mengadaptasi pohon sedikit) yang dapat Anda tulis ke file hasil.Seluruh prosedur berjalan dalam waktu O (n + Nm) jika n adalah panjang
FILE_B
,N
adalah jumlah barisFILE_A
dan m adalah panjang dari garis terpanjang dalamFILE_A
- ini pada dasarnya adalah runtime linier. Mengalahkan waktu kuadratik yang dibutuhkan pendekatan orisinal Anda dengan besaran.sumber
Saya menemukan
--mmap
bendera belakangan ini, tidak memiliki kesempatan untuk mengujinya, tetapi saya akan senang mendengar tentang temuan Anda. Berikut ini deskripsi dari halaman manual:Lihat ini atau ini untuk info lebih lanjut tentang
mmap
.sumber
--mmap
dosis itu tidak membuang apa pun, saya akan merekomendasikan lari dengan--mmap
, dan satu tanpa. Dan kemudian gunakanwc
untuk melihat bahwa Anda memiliki jumlah output yang sama - ini harus menjadi tes yang kuat mengingat kami berlari 2 kali grep, dan hanya sebuah flag yang berbeda.kenapa tidak Anda letakkan file itu dalam basis data database yang benar-benar bagus dalam melakukan penggabungan yang efisien, hash, nested loop, bergabung seperti ini. Dan mereka sangat baik dalam menggunakan memori virtual
sumber