Kinerja sed
vs. tail
untuk menghapus baris pertama file
TL; DR
sed
sangat kuat dan serbaguna, tetapi inilah yang membuatnya lambat, terutama untuk file besar dengan banyak baris.
tail
tidak hanya satu hal sederhana, tetapi yang dilakukannya dengan baik dan cepat, bahkan untuk file yang lebih besar dengan banyak baris.
Untuk file berukuran kecil dan menengah, sed
dan tail
berkinerja sama cepat (atau lambat, tergantung pada harapan Anda). Namun, untuk file input yang lebih besar (beberapa MB), perbedaan kinerja tumbuh secara signifikan (urutan besarnya untuk file dalam kisaran ratusan MB), dengan tail
kinerja yang jelas lebih baik sed
.
Percobaan
Persiapan Umum:
Perintah kami untuk menganalisis adalah:
sed '1d' testfile > /dev/null
tail -n +2 testfile > /dev/null
Perhatikan bahwa saya mem-piping output ke /dev/null
setiap kali untuk menghilangkan output terminal atau file menulis sebagai bottleneck kinerja.
Mari kita mengatur disk RAM untuk menghilangkan disk I / O sebagai hambatan potensial. Saya pribadi sudah tmpfs
memasang di /tmp
jadi saya hanya menempatkan saya di testfile
sana untuk percobaan ini.
Kemudian saya pernah membuat file uji acak yang berisi jumlah baris tertentu $numoflines
dengan panjang garis acak dan data acak menggunakan perintah ini (perhatikan bahwa itu pasti tidak optimal, itu menjadi sangat lambat untuk sekitar> 2M baris, tetapi siapa yang peduli, itu bukan hal yang kami analisis):
cat /dev/urandom | base64 -w0 | tr 'n' '\n'| head -n "$numoflines" > testfile
Oh, btw. laptop uji saya menjalankan Ubuntu 16.04, 64 bit pada CPU Intel i5-6200U. Hanya untuk perbandingan.
Mengatur waktu file besar:
Menyiapkan besar testfile
:
Menjalankan perintah di atas dengan numoflines=10000000
menghasilkan file acak yang berisi 10M baris, menempati sedikit lebih dari 600 MB - ini cukup besar, tetapi mari kita mulai dengan itu, karena kita dapat:
$ wc -l testfile
10000000 testfile
$ du -h testfile
611M testfile
$ head -n 3 testfile
qOWrzWppWJxx0e59o2uuvkrfjQbzos8Z0RWcCQPMGFPueRKqoy1mpgjHcSgtsRXLrZ8S4CU8w6O6pxkKa3JbJD7QNyiHb4o95TSKkdTBYs8uUOCRKPu6BbvG
NklpTCRzUgZK
O/lcQwmJXl1CGr5vQAbpM7TRNkx6XusYrO
Lakukan lari berjangka waktu dengan besar kami testfile
:
Sekarang mari kita lakukan hanya menjalankan satu waktu dengan kedua perintah terlebih dahulu untuk memperkirakan dengan apa yang kita kerjakan.
$ time sed '1d' testfile > /dev/null
real 0m2.104s
user 0m1.944s
sys 0m0.156s
$ time tail -n +2 testfile > /dev/null
real 0m0.181s
user 0m0.044s
sys 0m0.132s
Kami sudah melihat hasil yang sangat jelas untuk file besar, tail
besarnya lebih cepat dari sed
. Tapi hanya untuk bersenang-senang dan untuk memastikan tidak ada efek samping acak yang membuat perbedaan besar, mari kita lakukan 100 kali:
$ time for i in {1..100}; do sed '1d' testfile > /dev/null; done
real 3m36.756s
user 3m19.756s
sys 0m15.792s
$ time for i in {1..100}; do tail -n +2 testfile > /dev/null; done
real 0m14.573s
user 0m1.876s
sys 0m12.420s
Kesimpulannya tetap sama, sed
tidak efisien untuk menghapus baris pertama file besar, tail
harus digunakan di sana.
Dan ya, saya tahu konstruksi loop Bash lambat, tapi kami hanya melakukan iterasi yang relatif sedikit di sini dan waktu yang dibutuhkan loop polos tidak signifikan dibandingkan dengan sed
/ tail
runtimes.
Pengaturan waktu file kecil:
Menyiapkan kecil testfile
:
Sekarang untuk kelengkapan, mari kita lihat kasus yang lebih umum bahwa Anda memiliki file input kecil dalam kisaran kB. Mari kita buat file input acak dengan numoflines=100
, tampak seperti ini:
$ wc -l testfile
100 testfile
$ du -h testfile
8,0K testfile
$ head -n 3 testfile
tYMWxhi7GqV0DjWd
pemd0y3NgfBK4G4ho/
aItY/8crld2tZvsU5ly
Lakukan lari waktunya dengan kecil kami testfile
:
Karena kita dapat mengharapkan pengaturan waktu untuk file kecil seperti itu berada dalam kisaran beberapa milidetik dari pengalaman, mari kita lakukan 1000 iterasi segera:
$ time for i in {1..1000}; do sed '1d' testfile > /dev/null; done
real 0m7.811s
user 0m0.412s
sys 0m7.020s
$ time for i in {1..1000}; do tail -n +2 testfile > /dev/null; done
real 0m7.485s
user 0m0.292s
sys 0m6.020s
Seperti yang Anda lihat, waktunya sangat mirip, tidak ada banyak untuk menafsirkan atau bertanya-tanya. Untuk file kecil, kedua alat sama-sama cocok.
sed
lebih portabel: "+2" untuktail
berfungsi dengan baik di Ubuntu, yang menggunakan GNUtail
, tetapi tidak akan berfungsi pada BSDtail
.