GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara membuat skrip sed ini lebih cepat?

Pengujian saya menunjukkan bahwa sed dapat menjadi terikat CPU dengan mudah pada hal seperti ini. Jika Anda memiliki mesin multi-core, Anda dapat mencoba memunculkan beberapa sed proses dengan skrip yang terlihat seperti ini:

#!/bin/sh
INFILE=data.txt
OUTFILE=fixed.txt
SEDSCRIPT=script.sed
SPLITLIMIT=`wc -l $INFILE | awk '{print $1 / 20}'`

split -d -l $SPLITLIMT $INFILE x_

for chunk in ls x_??
do
  sed -f $SEDSCRIPT $chunk > $chunk.out &
done

wait 

cat x_??.out >> output.txt

rm -f x_??
rm -f x_??.out

Coba ubah dua baris pertama menjadi:

s/[ \t]*|[ \t]*/|/g

Hal terbaik yang dapat saya lakukan dengan sed adalah skrip ini:

s/[\s\t]*|[\s\t]*/|/g
s/[\s\t]*$//
s/^|/null|/

Dalam pengujian saya, ini berjalan sekitar 30% lebih cepat dari skrip sed Anda. Peningkatan kinerja berasal dari menggabungkan dua regexen pertama dan menghilangkan flag "g" jika tidak diperlukan.

Namun, 30% lebih cepat hanyalah peningkatan ringan (seharusnya masih memakan waktu sekitar satu setengah jam untuk menjalankan skrip di atas pada file data 1GB Anda). Saya ingin melihat apakah saya bisa melakukan yang lebih baik.

Pada akhirnya, tidak ada metode lain yang saya coba (awk, perl, dan pendekatan lain dengan sed) yang bernasib lebih baik, kecuali - tentu saja - implementasi C biasa. Seperti yang diharapkan dengan C, kodenya agak bertele-tele untuk diposkan di sini, tetapi jika Anda menginginkan program yang mungkin lebih cepat daripada metode lain di luar sana, Anda mungkin ingin melihatnya.

Dalam pengujian saya, implementasi C selesai sekitar 20% dari waktu yang dibutuhkan untuk skrip sed Anda. Jadi, mungkin diperlukan sekitar 25 menit atau lebih untuk berjalan di server Unix Anda.

Saya tidak menghabiskan banyak waktu untuk mengoptimalkan implementasi C. Tidak diragukan lagi ada sejumlah tempat di mana algoritme dapat ditingkatkan, tetapi terus terang, saya tidak tahu apakah mungkin untuk memangkas waktu yang signifikan melebihi apa yang sudah dicapai. Jika ada, saya pikir itu pasti menempatkan batas atas pada kinerja seperti apa yang dapat Anda harapkan dari metode lain (sed, awk, perl, python, dll).

Edit: Versi aslinya memiliki bug kecil yang menyebabkannya mencetak hal yang salah di akhir output (misalnya dapat mencetak "null" yang seharusnya tidak ada). Saya punya waktu hari ini untuk melihatnya dan memperbaikinya. Saya juga mengoptimalkan panggilan ke strlen() yang memberinya sedikit peningkatan kinerja.


Linux
  1. Cara membuat VPN

  2. Cara membuat perintah alias berfungsi di skrip bash atau file bashrc

  3. Cara menguji skrip PHP

  1. Bagaimana Cara Membuat Variabel Lingkungan "diekspor" Dalam Skrip Shell Tetap Di Sekitar?

  2. Bagaimana cara membuat file jarang?

  3. Bagaimana cara membuat skrip Python dijalankan sebagai layanan?

  1. Bagaimana Cara Men-debug Skrip Bash?

  2. Mengapa Scp Sangat Lambat Dan Bagaimana Cara Mempercepatnya?

  3. Bagaimana Cara Membuat Skrip A Sebagai Root Secara Retroaktif?