11

Cからシェルスクリプトに移行したプログラムのパフォーマンスへの影響はどれほど悪いのだろうかと思っていました。

私は集中的なI/O操作を行っています。

たとえば、Cでは、ファイルシステムファイルから読み取り、別のファイルに書き込むループがあります。私は一貫した関係なしに各行の一部を取っています。私はこれをポインターを使ってやっています。本当にシンプルなプログラム。

シェルスクリプトでは、行を移動するために、を使用して${var:(char):(num_bytes)}います。各行の処理が終了したら、それを別のファイルに連結します。

"$out" >> "$filename"

プログラムは次のようなことをします:

while read line; do
    out="$out${line:10:16}.${line:45:2}"
    out="$out${line:106:61}"
    out="$out${line:189:3}"
    out="$out${line:215:15}"
    ...
    echo "$out" >> "outFileName"

done < "$fileName"

問題は、Cが400MBのファイルを処理するのに30分ほどかかり、シェルスクリプトが15分かかることです。

何か間違ったことをしているのか、シェルスクリプトで正しい演算子を使用していないのかわかりません。

編集:行を処理するパターンがないため、awkを使用できません

「echo$out」>>「$outFileName」にコメントしてみましたが、あまり良くなりません。問題は${line:106:61}操作だと思います。助言がありますか?

ご協力いただきありがとうございます。

4

3 に答える 3

4

あなたの説明に基づいて、シェルスクリプトで新しいプロセスを生み出しているのではないかと思います。もしそうなら、それはあなたの時間が行くところです。新しいプロセスをフォーク/実行するには、多くのOSリソースが必要です。

于 2012-10-26T14:29:24.740 に答える
3

寄付者とディートリッヒが推測したように、私はAWK言語について少し調査しましたが、彼らが言ったように、それは完全な成功でした。これがAWKプログラムの小さな例です:

#!/bin/awk -f
{
    option=substr($0, 5, 9);

    if (option=="SOMETHING"){
        type=substr($0, 80, 1)
        if (type=="A"){
            type="01";
        }else if (type=="B"){
            type="02";
        }else if (type=="C"){
            type="03";
        }

        print substr($0, 7, 3) substr($0, 49, 8) substr($0, 86, 8) type\
        substr($0, 568, 30) >> ARGV[2]

    }
}

そしてそれは魅力のように機能します。500MBのファイルを処理するのにわずか1分かかります

于 2012-11-02T16:33:01.153 に答える
2

Cプログラムの何が問題になっていますか?壊れていますか?維持するのが難しすぎる?柔軟性がありませんか?あなたはCの専門家というよりもシェルの方ですか?

壊れていない場合は、修正しないでください。

Perlを見るのも選択肢かもしれません。Cよりも変更が簡単で、I/Oも高速です。また、Perlではシェルよりも役に立たないフォークを作成するのがはるかに困難です。

Cプログラムの機能を正確に教えていただければ、Unixツールボックスにsed、grep、awk、またはその他のギズモを使用した、シンプルで超光速のソリューションがあるかもしれません。言い換えれば、あなたが実際に達成したいことを教えてください。あなたが実際の目標に向かって一歩であると思うことを追求している間、あなたが遭遇したいくつかのランダムな問題を解決するように私たちに頼まないでください。

了解しました。シェルスクリプトの問題の1つは、で繰り返されることopenですecho "$out" >> "outFileName"。代わりにこれを使用してください:

while read line; do
    echo "${line:10:16}.${line:45:2}${line:106:61}${line:189:3}${line:215:15}..." 
done < "$fileName" > "$outFileName"

別の方法として、ユーティリティを使用するだけcutです(ただし、最初の部分の後にドットが挿入されないことに注意してください)。

cut -c 10-26,45-46,106-166 "$fileName" > "$outFileName"

分かりますか?

于 2012-10-26T15:12:16.810 に答える