- PR -

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

投稿者投稿内容
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-02-18 12:28
【サブスレッド】iStationさん指定のC/C++作成のDllを使うと早くなる理由

引用:

NAL-6295さんより:

そもそも、.NET開発環境でアンマネージドな、つまりWin32な開発ができるのは、
C++だけです。
VB.NETもC#.NETもコンパイル後はMSILが生成されるだけです。



ここの「マネージド コードとマネージド データとは? 」の一文である
デフォルトと言う言葉の意味を「設定変更が可能」と読み取ってしまいました。 ^^;

度々、ご返答ありがとうございます。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2004-02-18 12:34
NAL-6295さんのコメントとかぶりますが、

引用:

はにまるさんの書き込み (2004-02-18 11:54) より:
【サブスレッド】iStationさん指定のC/C++作成のDllを使うと早くなる理由

 NAL-6295 さんへ

  ご返答とご指摘ありがとうございます。
  .Net 言語の内部処理は全言語、一緒になると勘違いしていました。
  勉強になります。



.NET対応言語で作成したプログラムはビルド後はILコードになります。
コンパイラの実装による最適化等の違いは多少でるでしょうけれど、それは別として、
使っている命令が同じであれば、同じILコードになります。

しかし、このスレッドで話題に上がっているC/C++のDLLの話は、
Managed C++によるDLLではなく、Win32向けのDLLで.NETとは直接は関係ありません。

VC++.NETは、.NET対応と.NET非対応の両方の側面を持っています。
.NETのDLLも作れますし、Win32用のDLLも作れるということで、
.NETのDLLを作るときは、.NET対応言語で、(構文も通常のものにプラスアルファ、.NET用の記述をしないといけません)
Win32用DLLを作るときは、.NET非対応言語と言えます。。

引用:

はにまるさんの書き込み (2004-02-18 11:54) より:

  追加質問です。調査し切れなかったのですが、
  VB.Netの実行モジュールは、「マネージド」コードがデフォルト
  記述されていました。
  初心者の考えですが、VBのコンパイルを「アンマネージド」指定で行い
  ネイティブコードに変換すれば、DLL対策と一緒の利点を得れると考えました。



「VB.Netの実行モジュールは、「マネージド」コードがデフォルト
という記述はどこにどのように記述されていたのでしょうか?
(この文章そのままなのですか?)

VB.NETやC#の場合はマネージドコードしか作れませんが、
アンマネージドコードをコールすることはできます。
アンマネージドコードをコールした場合、その部分はアンマネージドなので、
デフォルトはマネージドコードという文章表現になっているだけでは?

-- 追記ここから --
ニアミスですね。.NET Framework FAQの文面でしたか。
確かに紛らわしい表現ですね。日本語訳が悪いのかと原文を見てましたが、
原文でも「by default」となっていますね。

#裏技でアンマネージドにできたりして:-)

-- 追記ここまで --


[ メッセージ編集済み 編集者: よねKEN 編集日時 2004-02-18 12:43 ]
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-02-18 12:45
【サブスレッド】iStationさん指定のC/C++作成のDllを使うと早くなる理由
はにまるです。

 よねKENさんへ

  丁寧な説明ありがとうございます。
  より一層の理解が深まりました。

  文書は、2つ前の投稿でリンクを貼っています。

  「C++によるアンマネージドのDLL処理」が何故有効なのか理解出来ました。
  パフォーマンス対応の一つの対策案として知識が増えました。 ^^

  当スレッドで質問していなかったら、
  マネージドで作成されたDLLを作成指示して意味不明な事をやっていました。
くまのぷーさん
常連さん
会議室デビュー日: 2003/12/18
投稿数: 34
投稿日時: 2004-02-18 13:40
Run Timeのテストをしてみました。
以下のコードでテストしたところ、1次元の配列の計算について、

@はAの約3.5倍(a=a+b*c)
BはCの約85倍 (配列のinitialize)
BはDの約3.8倍 (配列の配列のinitialize)

のスピードでした。
ところが、実際のプログラムのInitializeでは、思うようなパフォーマンスが出ないので、いろいろやったら、Redimの結果は、配列の多さや、Redimを行うタイミングで変わり、場合によってはC++と同じスピードが出る場合もあるという感じでした。

ループのよる計算のほうは、変数を増やすとその差が開くようです。

ループの計算は実際のプログラムではテストしていませんが、おいおい結果を報告したいと思います。




Dim A(1150) As Double
Dim B(1150) As Double
Dim C(1150) As Double
Dim D(1150) As Double
Dim D1(10000)() As Double
Dim i, j, k, kmax As Integer
Dim StartTime As Double
Dim EndTime As Double
Dim SpanCalc As Double

kmax = 9999

StartTime = DateTime.Now.ToOADate
  For k = 0 To kmax
@ i = Matrix.CalcMatrix1(A(0), B(0), C(0), 1149)
Next k
EndTime = DateTime.Now.ToOADate
SpanCalc = EndTime - StartTime
Console.WriteLine("Start:{0}, End:{1}, Span:{2}", StartTime, EndTime, SpanCalc)

StartTime = DateTime.Now.ToOADate
For k = 0 To kmax
For i = 0 To 1149
A A(i) = A(i) + B(i) * C(i)
Next
Next
EndTime = DateTime.Now.ToOADate
SpanCalc = EndTime - StartTime
Console.WriteLine("Start:{0}, End:{1}, Span:{2}", StartTime, EndTime, SpanCalc)


StartTime = DateTime.Now.ToOADate
For k = 0 To kmax
B Matrix.ClearMatrix1(D(0), 1149)
Next k
EndTime = DateTime.Now.ToOADate
SpanCalc = EndTime - StartTime
Console.WriteLine("Start:{0}, End:{1}, Span:{2}", StartTime, EndTime, SpanCalc)

StartTime = DateTime.Now.ToOADate
For k = 0 To kmax
C ReDim D(1150)
Next k
EndTime = DateTime.Now.ToOADate
SpanCalc = EndTime - StartTime
Console.WriteLine("Start:{0}, End:{1}, Span:{2}", StartTime, EndTime, SpanCalc)

ReDim D1(10000)(1150)

StartTime = DateTime.Now.ToOADate
For k = 0 To kmax
D ReDim D1(k)(1150)
Next k
EndTime = DateTime.Now.ToOADate
SpanCalc = EndTime - StartTime
Console.WriteLine("Start:{0}, End:{1}, Span:{2}", StartTime, EndTime, SpanCalc)


ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-18 14:27
コード:

For k = 0 To kmax
(4) ReDim D(1150)
Next k


コード:

For k = 0 To kmax
(5) ReDim D1(k)(1150)
Next k


ループ内でReDimするのは、何か理由がありますか?
ReDimのコストは馬鹿にできません。

たとえば(C#ですみませんが)、
コード:

string[][] l = new string[][] {
new string[]{ "a", "b", "c" },
new string[]{ "0", "1" }
};

for (int i = 0; i < l.Length; i++)
{
Console.Write("{0} : ", l[i].Length);
for (int j = 0; j < l[i].Length; j++)
{
Console.Write("{0} ", l[i][j]);
}
Console.WriteLine("");
}
Console.ReadLine();


のl[0]とl[1]みたいな、要素毎にサイズが異なるケースでない限り、ループ内でReDimするのは避けるべきかと。
もっと言えば、事前に配列のサイズを確定できないか、と。DBやExcelからデータを引っ張ろうとする時点で。

[ メッセージ編集済み 編集者: ぢゃん♪ 編集日時 2004-02-18 14:41 ]
くまのぷーさん
常連さん
会議室デビュー日: 2003/12/18
投稿数: 34
投稿日時: 2004-02-18 14:54
引用:

ぢゃん♪さんの書き込み (2004-02-18 14:27) より:
ループ内でReDimするのは、何か理由がありますか?
ReDimのコストは馬鹿にできません。



これは単にRunTimeのテストのためにこうしただけです。

実際のプログラムでは130個くらいの変数を1件の処理が終わるごとに初期化していますが、おっしゃるとおりこのコストが馬鹿にならず、C++のDllとどちらが早いか比較したいという意図で試してみました。
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-18 15:01
引用:

くまのぷーさんさんの書き込み (2004-02-18 14:54) より:

実際のプログラムでは130個くらいの変数を1件の処理が終わるごとに初期化していますが、


なぜ「1件の処理が終わるごとに」なのか、というところを知りたいような……

たしか初期化目的でReDimでしたね。
でも、それ全部が、本当に初期化が必要ですか?
上書きじゃ駄目ですか?

[ メッセージ編集済み 編集者: ぢゃん♪ 編集日時 2004-02-18 15:07 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-18 15:17
引用:

くまのぷーさんさんの書き込み (2004-02-18 14:54) より:

実際のプログラムでは130個くらいの変数を1件の処理が終わるごとに初期化していますが、おっしゃるとおりこのコストが馬鹿にならず、C++のDllとどちらが早いか比較したいという意図で試してみました。


 この言葉だけで判断するのも難ですが、プログラムの流れ、制御の仕方などの見直し、リファクタリングが必要かと。

Googlを、「vb 高速化」で検索
http://www5.ocn.ne.jp/~minute/article/vb/a7.html
簡単な高速化手法

http://www011.upp.so-net.ne.jp/flatsoft/soft/fs_about_vbcheck.html
ソースを静的解析して高速化を手助けするツール
VB6.0用なので、コレがチェックする項目を自分で確認する

http://www3.plala.or.jp/sardonyx/smart/
ここの「VB Tips」に高速化のtipsがある

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