データファイルを解析し、1100 x 1300 グリッドで満たされた 5 つの出力ファイルを書き込む Perl スクリプトがあります。スクリプトは機能しますが、私の意見では、ぎこちなく、おそらく非効率的です。スクリプトも継承されたコードであり、読みやすくするために少し変更しています。それでも、それは混乱です。
現時点では、スクリプトはデータファイル (~4Mb) を読み取り、それを配列に配置します。次に、配列をループして内容を解析し、値を別の配列にプッシュし、最後にそれらを別の for ループでファイルに出力します。特定のポイントの値が見つからない場合は、9999 が出力されます。ゼロは許容値です。
データファイルには 5 つの異なるパラメーターがあり、それぞれが独自のファイルに書き込まれます。
データの例:
data for the param: 2
5559
// (x,y) count values
280 40 3 0 0 0
280 41 4 0 0 0 0
280 42 5 0 0 0 0 0
281 43 4 0 0 10 10
281 44 4 0 0 10 10
281 45 4 0 0 0 10
281 46 4 0 0 10 0
281 47 4 0 0 10 0
281 48 3 10 10 0
281 49 2 0 0
41 50 3 0 0 0
45 50 3 0 0 0
280 50 2 0 0
40 51 8 0 0 0 0 0 0 0 0
...
data for the param: 3
3356
// (x,y) count values
5559は、現在のパラメーターへのデータ行の数です。データ行は次のようになります: x、y、その特定のポイントの連続する x 値の数、そして最後にvalues。パラメータ間に空行があります。
先ほど言ったように、スクリプトは機能しますが、これははるかに簡単かつ効率的に実行できると思います。方法がわかりません。ですから、ここが自己改善のチャンスです。
配列と for ループの複雑な組み合わせよりも、この問題へのより良いアプローチは何でしょうか?
編集:
これについてもっと明確にするべきでした、ごめんなさい。
出力は、データ ファイルから読み取った値で満たされた 1100 x 1300 グリッドです。各パラメータは異なるファイルに書き込まれます。データ行の複数の値は、その行に x(+n), y ポイントのデータがあることを意味します。
更新:
ソリューションをテストしたところ、驚いたことに、元のスクリプトよりも遅くなりました (~3 秒)。ただし、スクリプトは最大 50% 小さいため、スクリプトの機能を実際に理解するのがはるかに簡単になります。この場合、それは 3 秒の速度向上よりも重要です。
古いスクリプトのコードの一部を次に示します。そこから基本的な考え方を理解していただければ幸いです。なぜ速いのですか?
for my $i (0..$#indata) { # Data file is read to @indata
...
if($indata[$i] =~ /^data for the param:/) {
push @block, $i; # data borders aka. lines, where block starts and ends
}
...
}
# Then handle the data blocks
for my $k (0..4) { # 5 parameters
...
if( $k eq '4') { # Last parameter
$enddata = $#indata;
}
else {
$enddata = $block[$k+1];
}
...
for my $p ($block[$k]..$enddata) { # from current block to next block
...
# Fill data array
for(my $m=0 ; $m<$n ; $m++){
$data[$x][$y] = $values[$m];
}
}
print2file();
}