この投稿の個人情報。削除されました。
2 に答える
bashスクリプトの問題は、非常に柔軟で強力ですが、ほぼすべての新しいプロセスを作成し、フォークに費用がかかることです。ループの各反復で、 3× echo
、2× awk
、1× sed
、および1×を生成しperl
ます。1つのプロセス(したがって、1つのプログラミング言語)に制限すると、パフォーマンスが向上します。
output.txt
次に、への呼び出しで毎回読み直しますperl
。IOは常に遅いので、メモリがある場合はファイルのバッファリングがより効率的です。
マルチスレッドは、ハッシュの衝突がなければ機能しますが、プログラミングは困難です。Perlに変換するだけで、PerlをマルチスレッドPerlに変換するよりもパフォーマンスが大幅に向上します。[要出典]
あなたはおそらく次のようなものを書くでしょう
#!/usr/bin/perl
use strict; use warnings;
open my $cracked, "<", "cracked.txt" or die "Can't open cracked";
my @data = do {
open my $output, "<", "output.txt" or die "Can't open output";
<$output>;
};
while(<$cracked>) {
my ($hash, $seed, $pwd) = split /:/, $_, 3;
# transform $hash here like "$hash =~ s/foo/bar/g" if really neccessary
# say which line we are at
print "at line $. with pwd=$pwd\n";
# do substitutions in @data
s/\Q$hash\E/$hash ( $pwd )/ for @data;
# the \Q...\E makes any characters in between non-special,
# so they are matched literally.
# (`C++` would match many `C`s, but `\QC++\E` matches the character sequence)
}
# write @data to the output file
(テストされていないか、何もありません、保証はありません)
これは依然としてO(n²)ソリューションですが、bashスクリプトよりもパフォーマンスが優れています。ハッシュコードでインデックス付けされたハッシュツリーに編成する場合は、O(n)に減らすことができることに注意してください。@data
my %data = map {do magic here to parse the lines, and return a key-value pair} @data;
...;
$data{$hash} =~ s/\Q$hash\E/$hash ( $pwd )/; # instead of evil for-loop
実際には、ハッシュツリーにハッシュコードを含むすべての行を含む配列への参照を格納するため、前の行はむしろ
my %data;
for my $line (@data) {
my $key = parse_line($line);
push @$data{$key}, $line;
}
...;
s/\Q$hash\E/$hash ( $pwd )/ for @{$data{$hash}}; # is still faster!
一方、8E7要素を使用したハッシュは正確に機能しない可能性があります。答えはベンチマークにあります。
私の仕事のログを解析するとき、私はこれを行います:N個の部分のファイルを分割します(N = num_processors); 分割点を\nに揃えます。Nスレッドを開始して、各パーツを動作させます。非常に高速に動作しますが、ハードドライブがボトルネックになっています。