- PR -

VB.VETで、処理速度を早くしたいのですが

投稿者投稿内容
iStation
大ベテラン
会議室デビュー日: 2003/12/08
投稿数: 158
投稿日時: 2004-02-17 15:03
引用:

くまのぷーさんさんの書き込み (2004-02-17 13:51) より:
>iStationさん

10倍早くなるというのは、大変なことなので、再考させてください。

ただ、本当に素人なので、具体的な利用方法を教えていただきたいのですが

C/C++の開発環境があるとしたら、どういう手順でDLL化して、
VB.NETではどのように利用すればよいのでしょうか。
...


前出のサンプルコードをVC/C++の
Win32 (x86) Dynamic-Link Library プロジェクトとしてコンパイルし、
出来たDLLをVB.NET側から、
<DllImport("Matrix.DLL", EntryPoint:="_CalcMatrix@20")>
で呼び出します。
大体の作業の流れはこんな感じですが...
くまのぷーさん
常連さん
会議室デビュー日: 2003/12/18
投稿数: 34
投稿日時: 2004-02-17 15:11
ありがとうございました。

ところで、これはVisualStudio.netの中のC++でも良いですか?
素人考えですいません。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-17 15:30
情報がいろいろ氾濫して大変だと思いますが、整理してくださいね。

引用:

くまのぷーさんさんの書き込み (2004-02-17 13:39) より:

a(i,j)=a(i,j)+b(1,j)*c(i,J)

のaはSQLServer、bとcはエクセルのデータなので、SQLでその処理を書こうという発想は無かったです。b、cをSQLServerに入れて、SQLで書けないか考えてみます。


 ほむらさんとすこしかぶりますが、b,cはエクセルのセルを直接参照しようとしていますか?もしそうなら恐ろしく遅くなりますよ。先にメモリに取ってきておく方が速いです。

const cols as integer = 12
const rows as integer = 100

for col = 0 to cols - 1
 b(col, row) = エクセルオブジェクト.cells().value
 for row = 0 to rows - 1
  c(col, row) = エクセルオブジェクト.cells().value
  bc(col, row) = b(0, row) * c(col)
 next
next

for col = 0 to cols - 1
 for row = 0 to rows - 1
  a(col, row) += bc(col, row) ' VB.NETでこのような式が使えるようになりました
 next
next


 概して、厳密に型指定をする方が速くなります。VB.NETのプロジェクトのプロパティで、Option StrictをOnにしてみてください。今まで通っていたところが「型が一致していません」とか「暗黙の型変換は使えません」というエラーになりますが、実行時に判断しなくても良くなるので、速くなると思います(ちょっと不安)。

#####追加
 眺めていて思ったのですが、bは2次元配列にする必要はないですよね?!
コレもやはり、メモリアクセスに若干の差があるように思います。

 1200を一度に取る(1次元配列)よりも、100ずつ12に分ける方がメモリは取られやすくなります。1200の連続した領域を取るか(取れるところを探し回る)、100の連続した領域を取るか。もちろん、分けると12回探すので、スピードは低下します。
#マネージリソースだから関係ない?

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-02-17 17:22 ]
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-02-17 15:53
まずは、Jittaさんの仰っているように、a,b,cが配列なのかその他のオブジェクトなのかといった詳細な(コードの)情報等がないと、なぜ遅いのかは特定できないと思います。

重要なのは、コード上で改善できる(明らかに効率が悪いと思われる)コーディングをしているのか、データ数、処理の内容上、このくらいの処理時間がかかるのはある程度やむをえないのかをはっきりさせる必要があります。

正直な想像としては、おおぽかをやっていない限り、コードの細かい修正で改善できる時間はわずかなものだと思います。
まあ、あの例で示された程度の計算で、1200回ループを300万件で4時間とかって言うのは、ちょっと考えにくいところではありますが。

実際にはDB、Excelとのやり取りでほとんどの時間を費やしていたりしないですか?
# その解として、皆さんのDB上で処理してしまうというのも手ですが。

この辺を追求せずに仮にコードを修正しても、全く無駄になる可能性があります。
ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2004-02-17 16:12
ちょっと整理
コード:
for i=1 to 100 
for j = 1 to 12 
a1(i,j)=a1(i,j)+b1(1,j)*c1(i,J) 
a2(i,j)=a2(i,j)+b2(1,j)*c2(i,J) 
:
:
a100(i,j)=a100(i,j)+b100(1,j)*c100(i,J) 
next 
next 


1)100×12のループ内で100個の変数に値を設定
2)aはSQLからb、cはExcelから値を取得
3)2次元配列だったものを1次元配列にしたところ30時間から20時間に短縮

3)からあきらかにこのループで処理時間がかかっていると思われる

・ループ内の処理で遅いところはないか(エクセルのセルを直接参照など)
・無駄にループを呼んでいないか(300万件の処理で何回読んでいるか)
・ループ内処理で無駄がないか(a、b、cに値が設定されていないのに計算)

以上について一回調査してみてはどうでしょうか?

すくなくてもSQLの1レコードに対して上のループで計算する必要はないと思いますよ
iStation
大ベテラン
会議室デビュー日: 2003/12/08
投稿数: 158
投稿日時: 2004-02-17 16:32
引用:

くまのぷーさんさんの書き込み (2004-02-17 15:11) より:
ありがとうございました。

ところで、これはVisualStudio.netの中のC++でも良いですか?
素人考えですいません。


OKです!
C++でWin32プロジェクトを選んでください。
アプリケーションの設定でDLLの選択をお忘れなく...
kagura
常連さん
会議室デビュー日: 2003/03/26
投稿数: 27
投稿日時: 2004-02-17 17:40
利用できるなら
for を使うより、for each を利用した方がアクセスが速くなると思います
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-02-17 17:54
引用:

kaguraさんの書き込み (2004-02-17 17:40) より:
利用できるなら
for を使うより、for each を利用した方がアクセスが速くなると思います


場合によって逆はあると思いますが、これはないような…
どこかに情報があったりします?

スキルアップ/キャリアアップ(JOB@IT)