入力していただきありがとうございます。それに基づいて「宿題」を行い、実際の CSV データの 50MB サンプルを使用して結果を取得しました。
まず、PHP を使用してファイルを反復処理します。
$in = fopen("a.txt", "r");
$out = fopen("p.txt", "w+");
$start = microtime(true);
while(($line = fgets($in)) !== false) {
$converted = iconv("UTF-8", "EUC-JP//TRANSLIT", $line);
fwrite($out, $converted);
}
$elapsed = microtime(true) - $start;
echo "<br>Iconv took $elapsed seconds\r\n";
Iconv には 2.2817220687866 秒かかりました
それはそれほど悪くないと思うので、#bashでまったく同じアプローチを試したので、すべてのファイルをロードする必要はありませんが、代わりに各行を反復処理します(Lajos Veresの回答を理解しているため、正確には発生しない可能性があります)。実際、この方法は正確には効率的ではありませんでした (CPU は常に大きな負荷にさらされていました)。また、出力ファイルは他の 2 つよりも小さいですが、簡単に見てみると同じように見えます。したがって、bash スクリプトで間違いを犯したに違いありませんが、とにかくパフォーマンスにそのような影響を与えるべきではありません。
#!/bin/bash
echo "" > b.txt
time echo $(
while read line
do
echo $line |iconv -f utf-8 -t EUC-JP//TRANSLIT >> b.txt
done < a.txt
)
実 9m40.535s ユーザー 2m2.191s sys 3m18.993s
そして、私がメモリを独占すると予想していた古典的なアプローチですが、CPU /メモリの使用量をチェックすると、他のどのアプローチよりも多くのメモリを必要としないように見えたため、勝者になりました:
#!/bin/bash
time echo $(
iconv -f utf-8 -t EUC-JP//TRANSLIT a.txt -o b2.txt
)
実際の 0m0.256s ユーザー 0m0.195s システム 0m0.060s
より大きなファイル サンプルを取得して、2 つのより効率的な方法をテストし、メモリ使用量が大幅に増加しないことを確認しますが、結果は、bash でファイル全体を 1 回通過するのが最も効果的であると想定するのに十分明らかです。効率的です(PHPでファイル全体を配列/文字列にロードすることは決して良い考えではないと思うので、PHPではそれを試しませんでした)。