2009-04-13 9 views
1

私はテキストファイルを1行ずつ読み込み、固定長の文字列からデータを抽出するWindowsコンソールアプリケーションを作成しています。アプリケーションは今のところWindowsアプリケーションとして書かれていますが、後でWindowsコンソールアプリケーションに変換されます。私はアプリケーションがテキストを読んでから、データベースに挿入して、データベースからエクスポートするまでに時間がかかることに気づいた。複数のスレッドへ

複数のスレッドを使用すると処理が高速化されますか?私は、データを読み取るスレッドとデータベースにデータを挿入する別のスレッドを考えています。

どのような提案ですか?

編集:アプリケーションはVB.net

答えて

1

で行われようとしていることは、一般的に言うことは不可能だ - を見つけるための唯一の方法は、アプリを構築し、パフォーマンスをテストすることです。ボトルネックはDBインサートをする可能性があるが、マルチスレッドは、要因のホスト上depenndsをthibngsをスピードアップするかどうか:

  • アプリとthge同じマシン上で実行されているDBサーバですか?
  • 同じディスクを使用していますか?
  • 別のものと1つの挿入が競合する可能性がありますか?

あなたはアイデアを得ます。言いましたが、私はファイナンス業界で、DBアクセスのマルチスレッド化が大きな違いを生み出したサーバーを作成しました。しかし、これらは、データベースI/Oを余裕を持っている巨大なSunのエンタープライズサーバと話していたので、マルチスレッドアプリケーションからの要求でそれを氾濫させました。

1

複数のスレッドを使用すると、あるスレッドが別のスレッドがデータベースの挿入を実行している間に、あるスレッドがディスクから読み取っていることがあります。非常に大きなファイルを読んでいない限り、ほとんどの時間はおそらくデータベースに挿入され、ディスクI/Oの時間はちょうどノイズに過ぎません。

0

あなたがここで概説しているタスクは本質的にかなり連続的なものであるため、おそらくそれで多くは得られません。

-1

Windowsアプリを構築するために何を使用していますか? .Netを使用している場合は、スレッドプールを使用します。 Jeff Richterが開発したPower threadingという素晴らしいライブラリがあります。 Download

また、Windows OSでのスレッドの動作を理解してください。複数のスレッドを追加すると、役に立たない場合があり、しばしばそれを推奨しません。

0

アプリケーションをビルドするまでマルチスレッド化が役立つかどうかは分かりませんが、実際にはパフォーマンスが向上したように思えます。何かをする前に、アプリケーションのパフォーマンスを測定する必要があります。おそらく、非効率なコードがいくつかあるので、プロファイラを使用してボトルネックを特定してください。

0

複数のスレッドが必ずしもパフォーマンスを向上させるとは限りません。アクティビティを本当に並列に実行できるのであれば、基本的なマルチスレッドだけが動作します。多くのIO操作がデータを読み取る際に行われている場合は、試してみる価値があります。最善の方法はプロトタイプと検証です。

4

これはSQLデータベースと見なされます。

問題は、一度に1つのアイテムを実行している可能性があります。 SQLはそれを嫌っている。 SQLおよびSQLデータベースは、の項目のを設定して動作します。

したがって、トランザクションを開いて1,000個のアイテムを読み込んで挿入します。トランザクションコミットが何らかの理由で失敗した場合に備えて、再試行できるようにこれらのアイテムを保存します。

私はこのテクニックを使って20倍以上のあなたの説明と似たような仕事をするいくつかのPerlスクリプトをスピードアップすることができました。

私は使用しているMicrosoftライブラリがわかりませんが、ここにはDBIを使用したPerlのサンプルがあります。 AutoCommit => 0と$ dbh-> commitのように動作するようになっています。

#!/usr/bin/perl 

use strict; 
use DBI; 

my $dbname = 'urls'; 
my $user = 'postgres'; 
my $pass = ''; 

my $dbh = DBI->connect(
    "DBI:Pg:dbname=$dbname", 
    $user, 
    $pass, 
    { 'RaiseError' => 1, AutoCommit => 0 } 
); 

my $insert = $dbh->prepare(' 
    INSERT INTO todo (domain, path) 
    VALUES (?, ?) 
'); 

my $count = 0; 
while(<>) { 
    if($count++ % 1000 == 0) { 
     $dbh->commit; 
    } 
    chomp; 
    my ($one, $two) = split; 
    $insert->execute($one, $two); 
} 
$dbh->commit; 
$dbh->disconnect; 
+0

あなたはアイテムのセットでやる方法の詳細を教えてくれますか?チュートリアルや例が素晴らしいでしょう。ところで、私はMicrosoftエンタープライズライブラリを使用してデータを挿入しています。感謝。 – Jack

1

データベースへのデータのコミットは、時間がかかる操作です。アイテムを1つずつ送信するのではなく、バッチ単位でアイテムを収集して(たとえば1000)、データベースに送信してください。これにより、パフォーマンスが向上します。マルチスレッドは、このタイプのアプリケーションでは過剰です。

関連する問題