1

以下は、SQL クエリを整列テキスト テーブル形式にダンプするコードです。

sub sql_command {
    my ($self,$str) = @_;
    my $s = $self->{_db}->prepare($str) or die $!;
    $s->execute() or die $!;
    my $table;
    push @$table, [ map { defined $_ ? $_ : "undef" } @{$s->{'NAME'}}];
    while(my $row = $s->fetch) {
          push @$table, [ map{ defined $_ ? $_ : "undef" }@$row ];
    }
    return box_format($table);;
}


sub box_format {
    my $table = shift;
    my $n_cols = scalar @{$table->[0]};

    my $tb = Text::Table->new(\'| ', '', (\' | ','')x($n_cols-1), \' |+');
    $tb->load(@$table);
    my $rule = $tb->rule(qw/- +/);
    my @rows = $tb->body();
    return $rule, shift @rows, $rule, @rows, $rule
           if @rows;
}

出力は期待どおりです。ただし、パフォーマンスに関しては、約 5 MB のサイズの出力ファイルを処理するのに約 30 秒かかります。

パフォーマンスの点でそれを達成するためのより良い方法はありますか?

ありがとう!

4

1 に答える 1

2

そのコードには、いくつかのパフォーマンスの問題が考えられます。1 つ目は、ビルド$table時にデータ セット全体をメモリに取り込むことです。これは大量のメモリを消費する可能性があります。データが出てきたら、データをフォーマットする方がはるかに良いでしょう。これは、 を使用する代わりに を使用することを意味しText::Table->loadますText::Table->add

sub sql_command {
    my ($self,$sql) = @_;
    my $sth = $self->{_db}->prepare($sql) or die $!;
    $sth->execute() or die $!;

    return box_format_from_query($sth);
}

sub box_format_from_query {
    my $sth = shift;
    my $headers = [ map { defined $_ ? $_ : "undef" } @{$s->{'NAME'}}];
    my $num_cols = @$headers;

    my $table = Text::Table->new(\'| ', '', (\' | ','')x($num_cols-1), \' |+');
    while(my $row = $s->fetch) {
          $table->add(map { defined $_ ? $_ : "undef" } @$row );
    }

    my $rule = $tb->rule(qw/- +/);
    my @rows = $tb->body();
    return $rule, shift @rows, $rule, @rows, $rule
           if @rows;
}

2 番目のパフォーマンスの問題は、おそらく Text::Table 自体です。テーブル メソッドはデータのコピーに対して機能する (つまり、データを参照として渡さない) ため、大規模なデータ セットを念頭に置いて記述されている可能性は低くなります。確認する唯一の方法は、コードをプロファイリングすることです。Devel::NYTProfを見てください。コードがどこで時間を費やしているかを把握できるはずです。Text::Table メソッド内にあることが判明した場合は、作成者に連絡するか、フォーマットされた出力を生成する別の方法を検討する必要があります。

3 番目のパフォーマンスの問題は、クエリである可能性があります。クエリは表示されませんが、非効率的である可能性は十分にあります。Devel::NYTProf は、あなたが に多くの時間を費やしているかどうかを教えてくれます$sth->execute。もしそうなら、もう一つ質問があります。:)

于 2013-03-12T13:18:41.833 に答える