Saya mencoba membandingkan untuk membandingkan dua cara berbeda dalam memproses file. Saya memiliki sedikit data input tetapi untuk mendapatkan perbandingan yang baik, saya perlu mengulangi tes beberapa kali.
Daripada hanya mengulang tes, saya ingin menduplikasi data input beberapa kali (misalnya 1000) sehingga file 3 baris menjadi 3000 baris dan saya bisa menjalankan tes yang jauh lebih memuaskan.
Saya mengirimkan data input melalui nama file:
mycommand input-data.txt
perl
sangat efisien, ini dirancang untuk ini.Saya awalnya berpikir bahwa saya harus membuat file sekunder, tetapi saya hanya bisa mengulang file asli di Bash dan menggunakan beberapa pengalihan untuk membuatnya muncul sebagai file.
Mungkin ada selusin cara berbeda dalam melakukan loop tetapi di sini ada empat:
Metode ketiga ada improvisasi dari komentar maru di bawah ini dan membangun daftar nama file input untuk kucing.
xargs
akan memecah ini menjadi argumen sebanyak sistem akan memungkinkan. Ini jauh lebih cepat daripada n kucing terpisah.The
awk
way (terinspirasi oleh jawaban Terdon ini ) mungkin adalah yang paling optimal tetapi duplikat setiap baris pada suatu waktu. Ini mungkin cocok atau tidak cocok dengan aplikasi tertentu, tetapi kilat cepat dan efisien.Tapi ini menghasilkan dengan cepat. Bash keluaran cenderung jauh lebih lambat daripada yang bisa dibaca sehingga Anda harus menghasilkan file baru untuk pengujian. Untungnya itu hanya ekstensi yang sangat sederhana:
sumber
cat $(for i in {1..N}; do echo filename; done)
. Ini memiliki batasan ukuran arg, tetapi harus lebih cepat.Inilah
awk
solusinya:Ini pada dasarnya secepat @ Gnuc's Perl (saya berlari 1000 kali dan mendapatkan waktu rata-rata):
sumber
awk '{for(i=0; i<1000; i++)print}' input-data.txt
sehingga hanya mengeluarkan 1000 salinan setiap baris pada suatu waktu. Tidak akan cocok dengan semua kesempatan tetapi lebih cepat, lebih sedikit penundaan dan tidak perlu menyimpan seluruh file dalam RAM.123123123
itu baik-baik saja tetapi111222333
tidak. Versi Anda jelas lebih cepat daripada Gnouc, rata-rata pada 0,00297 detik. SUNTING: awal itu, saya membuat kesalahan, itu sebenarnya setara pada 0,004013 detik.Saya hanya akan menggunakan editor teks.
Jika Anda benar-benar perlu melakukannya melalui command-line (ini mengharuskan Anda untuk
vim
menginstal, karenavi
tidak memiliki:normal
perintah), Anda dapat menggunakan:Di sini,
-es
(atau-e -s
) membuat vim beroperasi secara diam-diam, sehingga tidak boleh mengambil alih jendela terminal Anda, dan-u NONE
menghentikannya dari melihat vimrc Anda, yang seharusnya membuatnya menjalankan sedikit lebih cepat daripada yang seharusnya (mungkin jauh lebih cepat, jika Anda menggunakan banyak plugin vim).sumber
Berikut ini adalah one-liner sederhana, tidak ada skrip yang terlibat:
Penjelasan
`yes input-data.txt | head -1000 | paste -s`
menghasilkan teksinput-data.txt
1000 kali dipisahkan oleh spasicat
sebagai daftar filesumber
xargs paste -s
? Ini berfungsi, tetapi tidak mempertahankan baris baru dalam file input.Saat bekerja pada skrip yang sama sekali berbeda, saya telah belajar bahwa dengan 29 juta baris teks, menggunakan
seek()
dan mengoperasikan data dengan sendirinya seringkali lebih cepat daripada secara garis demi garis. Gagasan yang sama diterapkan dalam skrip di bawah ini: kita membuka file, dan alih-alih membuka dan menutup file (yang dapat menambah overhead, meskipun tidak signifikan), kita tetap membuka file dan mencari kembali ke awal.Script itu sendiri cukup sederhana dalam penggunaan:
Untuk file teks 3 baris dan 1000 iterasi berjalan cukup baik, sekitar 0,1 detik:
Script itu sendiri tidak paling elegan, mungkin bisa disingkat, tetapi berhasil. Tentu saja, saya menambahkan beberapa bit tambahan di sana-sini, seperti
error_out()
fungsi, yang tidak perlu - itu hanya sentuhan kecil yang ramah pengguna.sumber
Kita dapat menyelesaikan ini tanpa file tambahan, atau program khusus, Bash murni (well, cat adalah perintah standar).
Berdasarkan fitur printf di dalam bash, kami dapat membuat string berulang):
Kemudian, kami dapat mengirim daftar 1000 nama file (berulang) dan memanggil kucing:
Dan akhirnya, kita bisa memberikan output pada perintah untuk dieksekusi:
Atau, jika perintah perlu menerima input di stdin:
Ya, dobel <diperlukan.
sumber
Saya akan menghasilkan file baru menggunakan Unix for loop:
sumber