C#でDataTableの更新を高速化!

このQ&Aのポイント
  • C#でDataTableの更新を高速化する方法を教えてください。
  • 現在、dataTblには1000件程度のデータが保存されており、Select()で300件程度を検索している状況です。しかし、for文の中でのデータの変更が非常に遅く、約10秒かかってしまいます。
  • どのようにすれば更新処理を高速化できるのでしょうか?助言をお願いします。
回答を見る
  • ベストアンサー

C# でDataTableの更新を高速化したい。

dataTblには1000件程度のデータが保存されています。 Select()で300件程度を検索して、ヒットした対象のデータの一部を変更しています。 以下がサンプルコード(モディファイしてあります。)です。 DataRow[] hitRow; hitRow = dataTbl.Select(str); for (int i = 0; i < hitRow.Length; i++) { hitRow[i][5] = "ABC"; <=== ここが遅い!! }  Select()は頻繁に行うわけでもなく、遅いとは思っていないのですが、for文の中身で非常に時間が掛ってしまいます。約10秒程度掛ります。  これを高速化したいと考えているのですが、何か良い手はないでしょうか?

  • naoja
  • お礼率45% (10/22)

質問者が選んだベストアンサー

  • ベストアンサー
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

データバインドしていませんか? BindingSource のバインドを止める → SuspendBinding / ResumeBinding コントロールの表示を止める → SuspendLayout/ResumeLayout

naoja
質問者

お礼

ありがとうございます。 SuspendBindingは気になっていたので、それ自体は止めていました。 私の質問にも問題があったのですが、上位でDataGridViewによる表示をおこなっておりました。 その結果、dataTableを変更することで、DataGridView側の表示フォーマットを変更するロジックが走ってしまっていたようです。 そういう意味では、SuspendLayoutを実施して表示を止めるようしてみたのですが、あまり効果は得られませんでした。 方向性として正しいと判断し、原因を追及したところ、Dataが更新されるたびに、DataGridView側のセルの各縦横幅を調整しに行っていたようです。 AutoSizeColumsModeおよびAutoSizeRowsModeがAllCellsになっていたことが原因でした。 これらの設定を、Noneにすると格段に速くなったのですが、表示状態が以前(AllCells)の時と比べ、異なってしまいました。 そこで、DisplayedCellsにすることで、表示上も支障なく速度の向上を得られることに成功しました。 方向性を与えて頂いてありがとう御座います。

関連するQ&A

  • vbでDataTableの抽出コピー

    vbでDataTableの抽出コピー DataTableから条件抽出したデータで別のDataTableを作成したい ・DataTable1から条件抽出したデータで別のDataTableを作成したい ・データの件数が違うだけでヘッダーなどの内容は同じにしたい Dim DataTable1 As DataTable ' 既にテーブルデータが入っているとする Dim DataTable2 As DataTable ' これに一部のデータとヘッダーを複写 Dim DataRow1 As DataRow ' DataRowの一時領域1 Dim DataRow2 As DataRow ' DataRowの一時領域2 <試作1:NG DataRowの使いまわしがきかない> DataTable2 = DataTable1.Clone For Each DataRow1 In DataTable1.Select(条件, ソート) DataTable2.Rows.Add(DataRow1) Next DataRow1 <試作2:NG ワンクッションかましただけではダメ> DataTable2 = DataTable1.Clone For Each DataRow1 In DataTable1.Select(条件, ソート) DataRow2 = DataRow1 DataTable2.Rows.Add(DataRow2) Next DataRow1 もしかして、個別セット以外に道はないのでしょうか? DataTable2 = DataTable1.Clone For Each DataRow1 In DataTable1.Select(条件, ソート) DataRow2 = DataTable2.NewRow DataRow2("item1") = DataRow1("item1") DataRow2("item2") = DataRow1("item2") DataRow2("item3") = DataRow1("item3") DataRow2("item4") = DataRow1("item4") DataRow2("item5") = DataRow1("item5") DataRow2("item6") = DataRow1("item6") DataRow2("item7") = DataRow1("item7") DataRow2("item8") = DataRow1("item8") DataTable2.Rows.Add(DataRow2) Next DataRow1 何か良い方法はありませんか?

  • サーブレットで複数値の受取り

    html(JSP)-formからSelectBox(multiple)を利用して 複数件のデータを取得したいと考えています。 servletで配列を利用して String abc[ ] = req.getParameterValues("list"); for (int i=0;i<abc.length;i++) { 処理1 } とすれば問題なく動くと思っていたのですが、 一件も選択されなかった場合にfor文でエラーとなっています。 abc.lengthで数えることができないのでしょうか? この場合、どのように対応すれば良いですか?

    • ベストアンサー
    • Java
  • mallocがうまく動かない

    コマンドライン引数で指定された文字列を逆順に返すプログラムを作るため 下記のようなプログラムを組みました。 ところが変数strの大きさがargv[1]より大きくなってしまいます。 どうすればよいのでしょうか。 #include <stdio.h> #include <stdlib.h> char *mstrrev (char *s); int main(int argc, char *argv[]){ char *str; str = mstrrev(*(argv+1)); printf("%s",str); free(str); } char *mstrrev (char *s){ int length,i; char *str; for(length=0;*(s+length)!='\0';length++); str = (char *)malloc(sizeof(char)*length); for(i=0;i<length;i++){ str[i] = s[length-1-i]; } return str; }

  • for文の()内のメソッドは?

    普通、String型の変数strの長さを知りたいと 思ったら str.length() で調べると思うのですが、 for 文中では、こういう風になりますよね‥‥ for (int i=0; str.length; i++) ただ、while文の()内では、ちゃんとlengthメソッドの 後に()を付けていたはず。 for文の場合の()は特殊なのかなと思うのですが、 これってどういう理屈なのでしょうか? # ;(セミコロン)がどうも怪しい感じなのですが。

    • ベストアンサー
    • Java
  • 数字文字の出現回数を表示するプログラム(C言語)

    タイトルのようなプログラムをCで作ろうとしています。ちなみに初学者です。 たとえば 32356695 と入力すると '0' appeared 0 times. '1' appeared 0 times. '2' appeared 1 times. '3' appeared 2 times. '4' appeared 0 times. '5' appeared 2 times. '6' appeared 2 times. '7' appeared 0 times. '8' appeared 0 times. '9' appeared 1 times. と表示されるようにしたいです。そこで以下のようなプログラムを組みましたが コンパイルは成功するもexeを実行すると数字入力後エラーメッセージが出ます。 ************************************************* #include<stdio.h> #include<string.h> #include<stdlib.h> int main(void) { int i; int count[10]={0}; int length; int digit; char str[100]; printf("Please input number:"); gets(str); length = strlen(str); for(i=0;i<length;i++){ if(str[i]>='0' && str[i]<='9'){ digit = atoi(&str[i]); count[digit]++; } } for(i=0;i<=9;i++){ printf("'%d' appeared %d times.\n",i,count[i]); } return(0); } ****************************************************** よくわからないのですが何故か文字列の長さを収納する変数lengthが1になているようです。 どうかお力添えください。お願いいたします。 コンパイラはbcc32、OSはWindowsXPです。

  • cプログラミングについて

    以下はsample.txtというファイルを読み込み、辞書順に並べるプログラミングですが、どう正しく 直したらよいかわかりません。間違っている場所を指摘していただけたらと思います。 (間違えだらけで申し訳ありません) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLINE 500 void mysort(char *word[MAXLINE]) { int i,j; char *tmp; for(i=0;;i++){ for(j=i+1;; j++){ if(strcmp(word[j],word[i])==1){ tmp=word[i]; word[i]=word[j]; word[j]=tmp; } } } } int main(void) { int i; FILE *fp; char str[MAXLINE]; fp= fopen("sample.txt", "r"); if (fp == NULL) { printf("fopen error\n"); exit(1); } while(( fgets( str, MAXLINE, fp )) != NULL) mysort(str); for(i=0;; i++) printf("%s\n", str[i]); return 0; }

  • javaプログラミングについて

    ただいまjavaプログラム勉強中でhit&blowを制作しております。 public static void main(String[] args) { Scanner scan = new Scanner(System.in); Random rand = new Random(); int[] answer = new int[4]; int[] input = new int[4]; int[] Number = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; int x = 10; for (int i = 0; i < 4; i++) { int select = (int) (Math.random() * x); answer[i] = Number[select]; Number[select] = Number[x - 1]; x--; } int count = 1; while (true) { System.out.println("4桁の異なる数値を入力"); int str_input = scan.nextInt(); // 代入 for (int i = 0; i < 4; i++) { input[i] = str_input; } // hit int hit = 0; for (int i = 0; i < 4; i++) { if (input[i] == answer[i]) { hit++; } } // blow int blow = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++){ if (i != j && input[i] == answer[j]) { blow++; } } } if (hit == 4) { System.out.println("4hit"); System.out.println("正解まで " + count + "回"); break; } else { System.out.println("Hit:" + hit + " Blow:" + (blow - hit)); count++; } } } } 数字が4桁で作っているのですが、数字や4桁以上を入力してしまった場合の表示は後にしようとして、先にhitとblowの判定を作ろうとしているのですが、上記で実行したところhitとblowの判定がされずhit:0blow:0と表示されてしまいます。解決策を教えてください。 自分で作ってみたものの、hit blowの判定方法があっているかも自信がないです。

    • ベストアンサー
    • Java
  • 構造体のコピーについて

    次のプログラムを実行してoriginalは偶数、copyは奇数を表示するようにしたいのですが、実行すると両方とも奇数になってしまいます。 正しく表示されるようにするにはどこを直せばいいのか教えてください。 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct structSample_ { unsigned int nmemb; /*配列の要素数 */ int *data; /* データを格納する配列 */ }Sample; /* 関数のプロトタイプ宣言 */ Sample *alloc_str ( unsigned int nmenb ); /* 新しい構造体を確保 */ /* main関数 */ int main ( void ) { Sample *original_str, *copy_str; unsigned int number = 10; int i; /* 構造体用のメモリ割り当て */ original_str = alloc_str ( number ); copy_str = original_str; /* original にデータを代入 */ for( i = 0; i < original_str->nmemb; i++ ) original_str -> data[i] = (i+1) * 2; /* 偶数を代入 */ /* original を copy に複製 */ copy_str = original_str; /* copy のデータを編集 */ for( i = 0; i < copy_str->nmemb; i++ ) copy_str->data[i]--; /* 奇数にする */ /* 結果の確認 * original には偶数が入っているはず */ printf( "original: " ); for( i = 0; i < original_str->nmemb; i++ ) printf( "%d ", original_str->data[i] ); printf( "\n" ); /* copy には奇数がはいっているはず */ printf( " copy : " ); for( i = 0; i < copy_str->nmemb; i++ ) printf( "%d ", copy_str->data[i] ); printf( "\n" ); return 0; }

  • C++ : cout << (数字) で実行時エラーが発生する理由

    ある特定の位置でcout を用いて数字を表示しようとするとエラーが発生してしまいます。 具体的には以下の関数内でのことなのですが、原因の分かる方がいましたら解答お願いします。 受け取った文字列を逆順にする関数です。 ---------------------------------------------------------- void rev_str(char *a) { int length = 0; cout << length; // ここでエラーが発生 while(true) { if(*(a + length) == '\0') break; length++; } for(int i = 0; i < length / 2; i++) { char temp = a[i]; a[i] = a[length - i - 1]; a[length - i - 1] = temp; } } --------------------------------------------------------- エラーの発生する部分ですが、数字ではなく文字・文字列なら問題なく表示されます。 このコードでは変数 length を表示しようとしていますが、length でなくても、またどのような『数』でも『この関数内』で cout を使用するとエラーが発生します。 この関数に何か間違いがあるのではないかと思うのですが、どうにも見つけることが出来ません。 コード全体はこの下に掲載します。 cout に何か制約があるのでしょうか。それとも、やはりコードのどこかに誤りがあるのでしょうか。わかる方がいましたら、解答お願いします。 全コード ------------------------------------------------------ #include <iostream> #include <cstring> using namespace std; void rev_str(char *a); void rev_str(const char *source, char *des); int main() { char a[80], b[80]; strcpy(a, "hello, world!"); rev_str(a, b); rev_str(a); cout << a << "\n"; cout << b << "\n"; return 0; } void rev_str(char *a) { int length = 0; cout << length; while(true) { if(*(a + length) == '\0') break; length++; } for(int i = 0; i < length / 2; i++) { char temp = a[i]; a[i] = a[length - i - 1]; a[length - i - 1] = temp; } } void rev_str(const char *source, char *des) { char *a = (char*)malloc(sizeof(source)); strcpy(a, source); rev_str(a); strcpy(des, a); free(a); }

  • string から unsigned char へ

    unsigned char* uchar_string(string* str) { int length = str->length(); const char* cchar = str->c_str(); unsigned char* uchar = new unsigned char[length+1]; for(int i=0; i=length; i++) { uchar[i] = (unsigned char)cchar[i]; } return uchar; } int main() { string str; cin >> str; unsigned char* uc; uc = uchar_string(&str); cout << uc; delete uctest; return 0; } このようにしたところ、cout << uc; が出力されず入力待ちとなり正常に動きませんでした。 原因がわからないです。原因と解決方法のご教授願います。

専門家に質問してみよう