C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: [VB6] open 書き込みバッファのデフォルトサイズ


(過去ログ 14 を表示中)

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■4337 / inTopicNo.1)  [VB6] open 書き込みバッファのデフォルトサイズ
  
□投稿者/ mあ (2回)-(2007/06/14(Thu) 12:19:34)

分類:[VB6 以前] 

マルチポスト(VB6 掲示板):
http://homepage1.nifty.com/MADIA/
タイトル:VB6 open 〜 Access Write As #inpFile の書き込みバッファのデフォルトサイズについて

※向こうで返信無さそう(興味無い?)なのでこちらでも意見を伺いたく。
双方にレス&進捗報告をするつもりです。
よろしくお願いします。m(__)m

open でシーケンシャルアクセスで 書き込みモードで ファイルをオープン。
このとき、バッファサイズを 32000 〜 65000 の範囲を指定することで
 参考:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/vb_k04.htm
書き込み処理を高速化出来る可能性があることは分かりましたが、
指定しないときのデフォルトサイズはどれくらいのものなんでしょうか?
また、バッファの吐き出し契機は?
 改行コード?(改行が多いデータの場合は逆に遅くなりそうな・・・)
 しきい値?(90%溜まったら吐き出し・・・とか)
 バッファ満タン?(普通に考えたらコレかな・・・)

ついでに、読込バッファのデフォルトサイズと先読み契機もご存知でしたら
教えてください。
読込はしきい値っぽいな・・・


# SVF 食わせ用CSVデータファイル出力に、現状3時間ですって・・・・(出力紙換算で600 枚程度)
# SQL=4割, CSV=6割 な実行時間比率
# SQL が時間かかりすぎなのはおいといてください。

引用返信 編集キー/
■4343 / inTopicNo.2)  Re[1]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ なちゃ (36回)-(2007/06/14(Thu) 14:30:41)
むしろどうやってCSVにしてるのかの方が影響が大きいと思いますよ。

全くバッファリングされずに直出力ならともかく、
常識的なバッファリングがどこかで行われているなら
そう極端には変わらない可能性が高いです。

ありがちなのは巨大なCSV全体をメモリ上で作成してるとか、
しかも全部文字列連結してるとかですね。

引用返信 編集キー/
■4344 / inTopicNo.3)  Re[2]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ なちゃ (37回)-(2007/06/14(Thu) 14:33:11)
てVB6ですね…
まあ似たような事情はそちらでも当てはまるかとは思います。
引用返信 編集キー/
■4345 / inTopicNo.4)  Re[2]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ Mr.T (61回)-(2007/06/14(Thu) 14:52:12)
Mr.Tです、こんにちは。

No4343 (なちゃ さん) に返信
> しかも全部文字列連結してるとかですね。

VB6.0なら、Midを利用する方が断然速いというテクニックがありましたね。
http://support.microsoft.com/kb/170964/

引用返信 編集キー/
■4346 / inTopicNo.5)  Re[3]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ ぽぴ王子 (216回)-(2007/06/14(Thu) 15:02:46)
ぽぴ王子 さんの Web サイト
No4345 (Mr.T さん) に返信
> Mr.Tです、こんにちは。
>
> ■No4343 (なちゃ さん) に返信
>>しかも全部文字列連結してるとかですね。
>
> VB6.0なら、Midを利用する方が断然速いというテクニックがありましたね。
> http://support.microsoft.com/kb/170964/

ちょっと懐かしいコレを思い出しました。
http://blogs.wankuma.com/rti/archive/2007/01/08/55000.aspx

ってあれ、ほとんど同じジャマイカ。
引用返信 編集キー/
■4347 / inTopicNo.6)  Re[3]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ 魔界の仮面弁士 (302回)-(2007/06/14(Thu) 15:09:05)
# SQL Server 2000 の DTS による CSV 作成は、けっこう高速だったような気が。うろ覚え。


No4337 (mあ さん) に返信
> このとき、バッファサイズを 32000 〜 65000 の範囲を指定することで
>  参考:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/vb_k04.htm
> 書き込み処理を高速化出来る可能性があることは分かりましたが、

記事の内容を読み違えているような……。
そもそも、Len 句に指定できる最大値は 32,767 ですよね。


No4345 (Mr.T さん) に返信
> VB6.0なら、Midを利用する方が断然速いというテクニックがありましたね。
> http://support.microsoft.com/kb/170964/

最大サイズが不定な時は、Mid ステートメントも使いにくいんですよね。
そんな時は、Dictionary.Join メソッドで連結すると、結構速くなります。
(速度面だけで見ると、Mid ステートメント法には到底敵いませんけど)

とはいえ、文字列連結せずに逐次 Print # しているなら、そっちの方が早かったり。
引用返信 編集キー/
■4349 / inTopicNo.7)  Re[3]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (3回)-(2007/06/14(Thu) 15:22:11)
No4344 (なちゃ さん) に返信
> てVB6ですね…
> まあ似たような事情はそちらでも当てはまるかとは思います。


> ありがちなのは巨大なCSV全体をメモリ上で作成してるとか、
おっしゃるとおりです。ですが、リリース後に巨大メモリ食い過ぎ処理な部分は
削除されております。が、本当に使用量を測ったのかどうかは疑わしく・・・
おそらく、VBがたまーに出す(あれってGCが利かないからしょうがなく出ちゃうの?)
「メモリが足りません」てエラーで強制終了しちゃうのを食い止めるための暫定処置
かと。

> しかも全部文字列連結してるとかですね。
おっしゃるとおりです。文字列連結ビンビンです。print "moji,moji2,..." が全ての基本
になっています。確か、VBには、ファイル出力の際に、配列を指定して、カンマ区切りで
出力するように出来たよーな、出来なかったような・・・Input は見たことあるのですが・・・


--

SQL は、Oracle/ストアド
20個くらい引数がある中身(まだ見てないです)も巨大そうなSQLをいっぱい実行して
3つのテンポラリテーブルを作成します。

VBはとてもきれいに書かれているのですけど、スピード度外視、綺麗さ重視なつくりです。
関数化と共通部分の抜き出しに注視されるあまり〜当時からかなり修正が入っているの
ですが、あとから修正した人間がこの作り方に慣れてないように見えます〜コピペ主体
というか、動けばいいや、というか・・・どの時点で動きが極端に遅くなったのかは、
ソースの読みと修正日付でうっすらぼんやり見えてくるでしょうが・・・と思ったら
言うまでもなく、作成当時から遅いようです。。。ダメだこりゃ。。。

動的SQLが少ないが呼ばれる回数は多いです。当然というか。
バインド変数多用して、ストアドコールしています。まぁここらへんはいいでしょう。
数も少ないし。でも、OraDynaset を取得した後が問題?、SQL の WHERE 句と同じことを
VBでやってるぽいです。てことは、ストアドは、全件取得のSQLで構成されていて、
VB側で適当に要らないデータを篩いわけしてCSV作ってよ、みたいな作りですね・・・
C/PRO-C なら、データベースでやるよりC側でやってもあまりスピードも変わらんような
気がしますが、VBだとさすがにまずいでしょうね。

ヘッダSQL発行
ヘッダ部読み {
 ヘッダのパラメータで胴体部SQL発行(動的SQL)
 胴体帳票1、帳票2 出力
 宛名出力
}

スピードアップのSE的希望は、いまの半分です。全体で30%程度の高速化ってとこ。
VB側は改善の余地大幅にありですから、まだいいですが、SQLはあまり得意じゃないので
触る気になれません。かと言ってVBもあまり得意じゃないのですが・・・

とりあえず、VBから触れ、との命により・・・

# ちゅーても、この指令を出してる本人の修正も結構入っているのに、修正している時点
# 遅いことに気づかなかったわけが無いだろうと・・・というか、やる気あんのか!と。

なちゃ様>
ご意見ありがとうございました。

とりあえず、バッファサイズを知ったところでどんなもんだ、という指摘も確かにそうなので
すが、知りたい欲求が高いため、引き続き情報をお寄せください。
知ったところで、最初から、32000〜65000 の範囲で使うことは確定なんですが・・・








引用返信 編集キー/
■4350 / inTopicNo.8)  Re[4]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (4回)-(2007/06/14(Thu) 15:28:46)
No4347 (魔界の仮面弁士 さん) に返信
> # SQL Server 2000 の DTS による CSV 作成は、けっこう高速だったような気が。うろ覚え。
>
>
> ■No4337 (mあ さん) に返信
>>このとき、バッファサイズを 32000 〜 65000 の範囲を指定することで
>> 参考:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/vb_k04.htm
>>書き込み処理を高速化出来る可能性があることは分かりましたが、
>
> 記事の内容を読み違えているような……。
> そもそも、Len 句に指定できる最大値は 32,767 ですよね。
読み違えています?バッファリングのことだと認識していたのですが・・・
fwrite() のバッファてデフォルト 4096〜8192 じゃないですか。あれと同じだと
理解していたのですが・・・ディスクへの物理アクセスを減らすことによる高速化
じゃなかったのか・・トホホ・・・

ご意見ありがとうございます。m(__)m


>
>
> ■No4345 (Mr.T さん) に返信
>>VB6.0なら、Midを利用する方が断然速いというテクニックがありましたね。
>>http://support.microsoft.com/kb/170964/
>
mid() 使うタイミングを計ります。
情報ありがとうございます。m(__)m

> 最大サイズが不定な時は、Mid ステートメントも使いにくいんですよね。
> そんな時は、Dictionary.Join メソッドで連結すると、結構速くなります。
> (速度面だけで見ると、Mid ステートメント法には到底敵いませんけど)
>
> とはいえ、文字列連結せずに逐次 Print # しているなら、そっちの方が早かったり。

ノンバッファリングの Print があるってことですか?
VB の書き込みはバッファリング無しが基本なんですか?




引用返信 編集キー/
■4351 / inTopicNo.9)  Re[5]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (5回)-(2007/06/14(Thu) 15:37:42)

>>とはいえ、文字列連結せずに逐次 Print # しているなら、そっちの方が早かったり。
>
> ノンバッファリングの Print があるってことですか?
> VB の書き込みはバッファリング無しが基本なんですか?

すみません、バイナリファイルとテキストファイルを履き違えてました。
ライトスルーでしたよね。CSVですから、改行コードがレコードデリミッタ
ですし、バッファの吐き出し契機が改行コードかどうかは不明ですが、
とりあえず、
Print # ,... Print VbCrLf
も高速化の手の一つですね。
C/C++から遠ざかって長いものですから忘れてました。
すみません。


引用返信 編集キー/
■4352 / inTopicNo.10)  Re[4]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ ちゃっぴ (26回)-(2007/06/14(Thu) 15:46:51)
ちゃっぴ さんの Web サイト
Disk I/O の buffer って IoPageLockLimit の size じゃありませんでしたっけ?
引用返信 編集キー/
■4353 / inTopicNo.11)  Re[5]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (6回)-(2007/06/14(Thu) 16:04:47)
No4352 (ちゃっぴ さん) に返信
> Disk I/O の buffer って IoPageLockLimit の size じゃありませんでしたっけ?

ご意見ありがとうございます。

http://journal.mycom.co.jp/special/2003/gigamemory/003.html

コレですね。

高速化で色々突っ込んだらたいして速度改善されなかったというオチはありがちです
が皆様の意見を参考に色々取り込んでみようと思っています。

引き続きよろしくお願いします。


引用返信 編集キー/
■4354 / inTopicNo.12)  Re[5]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ 魔界の仮面弁士 (303回)-(2007/06/14(Thu) 16:08:51)
2007/06/14(Thu) 16:30:47 編集(投稿者)
VB6 の高速化コード集。
可読性に難のあるコードも多いので、使いどころに注意。
http://www.xbeat.net/vbspeed/No4350 (mあ さん) に返信
>>記事の内容を読み違えているような……。
> 読み違えています?バッファリングのことだと認識していたのですが・・・
バッファです。バッファなんですが、記事中で書かれていた内容は、
 『32000 を指定すると高速アクセスできる。』
 『関数内で合計 65000 程度のバッファしか確保できない。』
であって、
 「32000 〜 65000 の範囲を指定することで、書き込み処理を高速化出来る」
では無いと思いますよ。

元の記事にもヘルプにも、65000 という値を Len に指定できるとは
書かれていませんし、実際に指定すると、実行時エラーとなりましたから。

> ノンバッファリングの Print があるってことですか?
> VB の書き込みはバッファリング無しが基本なんですか?

文字列連結の話は、たとえば
 Set RS = Con.Execute(SQL)
 Do Until RS.EOF
  S = S & RS.Collect("ID") & ","
  RS.MoveNext
 Loop
 Print #f, S;
のような書き方をすると低速であり、
 Set RS = Con.Execute(SQL)
 Do Until RS.EOF
  Print #f, RS.Collect("ID") ","
  RS.MoveNext
 Loop
の方が結果的には高速であった…という話です。

もっとも、Recordset のテキスト化なら、GetString メソッドを併用した方が早いですけれどね。


でもって、Mid ステートメントの件は:
------------
Dim S As String

S = "aaa"
Debug.Print StrPtr(S), "["; S; "]"
S = S & "bbb"
Debug.Print StrPtr(S), "["; S; "]"

S = "aaa   "
Debug.Print StrPtr(S), "["; S; "]"
Mid(S, 4) = "bbb"
Debug.Print StrPtr(S), "["; S; "]"
------------

後者(Midステートメント)では、同じアドレスがそのまま使われていることを確認できますが、
前者(& 演算子)では、文字列処理の前後で、変数のアドレスが変更されていることがわかります。

これは単純に連結すると、新たな文字列領域の確保・複写・元の領域の破棄が行われるためです。
そのため文字列が長くなればなるほど、加速度的に処理時間がかかるようになります。

Mid ステートメントは、最初に確保した文字列領域内を書き換える形で動作するので、
メモリの再確保等が行われず、高速に処理される…という話ですね。

引用返信 編集キー/
■4358 / inTopicNo.13)  Re[6]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (7回)-(2007/06/14(Thu) 16:46:33)
No4354 (魔界の仮面弁士 さん) に返信
> 2007/06/14(Thu) 16:30:47 編集(投稿者)
>
> VB6 の高速化コード集。
> 可読性に難のあるコードも多いので、使いどころに注意。
> http://www.xbeat.net/vbspeed/
>

了解しました。参考にします。


>
> ■No4350 (mあ さん) に返信
>
> 元の記事にもヘルプにも、65000 という値を Len に指定できるとは
> 書かれていませんし、実際に指定すると、実行時エラーとなりましたから。


これはこちらの勝手な想像が入っていました。ごめんなさいでした。

>
> もっとも、Recordset のテキスト化なら、GetString メソッドを併用した方が早いですけれどね。

これも、カンマの後ろにスペースが1個入らないなら検討してみます、というか
後で試してみます。


> でもって、Mid ステートメントの件は:

了解です。

いつも、丁寧な助言ありがとうございます。m(__)m



引用返信 編集キー/
■4359 / inTopicNo.14)  Re[6]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ 魔界の仮面弁士 (304回)-(2007/06/14(Thu) 17:13:20)
誤記とは思いますが、一応補足。


No4351 (mあ さん) に返信
> Print # ,... Print VbCrLf
> も高速化の手の一つですね。

vbCrLf の指定は不要です。
Print # ステートメントは、自動的に末尾に CrLf 改行を挿入しますので。


-- (1)末尾改行ありで出力するとき
Print #f, "abcdefg"
----------------------------------------

-- (2)末尾改行無しで出力するとき
Print #f, "abcdefg";
----------------------------------------

-- (3)改行だけを出力するとき
Print #f,
----------------------------------------

-- (4)末尾改行無しで、1行出力
Print #f, Tab(1);"abcdefg";
----------------------------------------


「最終行に改行を含める CSV 出力」では (1) を。

Do Until RS.EOF
  Debug.Print #f, CStr(F1.Value) & "," & CStr(F2.Value) & "," & CStr(F3.Value)
  RS.MoveNext
Loop


「最終行に改行を含めない CSV 出力」では (4) を。

Do Until RS.EOF
  Debug.Print #f, Tab(1); CStr(F1.Value) & "," & CStr(F2.Value) & "," & CStr(F3.Value);
  RS.MoveNext
Loop
引用返信 編集キー/
■4376 / inTopicNo.15)  Re[7]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (10回)-(2007/06/15(Fri) 02:50:55)
No4359 (魔界の仮面弁士 さん) に返信
> 誤記とは思いますが、一応補足。

誤記ではありません。VBに関しては魔界さんの足元にも及ばない、
初心者?レベルです。ただ、他の言語をかじっているので、VBも
Javaも似たようなもん、ぐらいの感覚ではあるのですけど。
言語体系・文法はまったく異なります(設計思想が根本的に違うから?)が、
時にVBの便利さをうらみ、時にVBの融通の利かなさに疼いていますw融通
利かないのは自分が覚えが悪いだけなんですけどね。


助言・指摘ありがとうございます。
結局本題の質問は対して意味が無いというか、まぁ、分かったところで
使いもしない、知識のレベルだけですので、皆様の挙げられた情報を元に
高速化を検討してみます。
結果は後日あらためて、”双方”の掲示板に報告します。

#
# タイトル、高速化について意見求む、の方が良かったかもしれませんね。
#

引用返信 編集キー/
■4655 / inTopicNo.16)  Re[6]: [VB6] open 書き込みバッファのデフォルトサイズ
□投稿者/ mあ (13回)-(2007/06/21(Thu) 15:49:39)
皆様>

既存VB-PGMの実行速度改善に取り組み、結果として90%程度の高速化を達成出来ました。
時間が無くそれぞれの実装タイミングでの新旧ソースの実行時間計測は行えませんでし
たが、実行速度改善に向けて取り組んだことを書きます。

(1) Strcat クラス の実装
  "文字列" & "文字列" ... 部を Strcat クラスメソッドに置き換え
(2) ODBC フェッチサイズ、フェッチ行数の設定
デフォルトで、フェッチサイズ:フェッチ行数=4096:100 でしたので、
30K : 12K に変更しました。
(3) VB ロジック改善

PGM概要
最終的に、SVF に食わせる CSV ファイルを2つ以上作成するというVB-PGMです。
サンプルデータは 8000 件、ファイルサイズは、本体:740Kバイト,サブ:8Kバイト
になります。本番時は、データ件数 20万件程度、帳票枚数で600 枚。

修正前CSV出力のみの実行時間:194 秒
修正後CSV出力のみの実行時間:14 秒

修正前ソースを精査したところ、なんと、ストアドでデータを一括で取得するのですが、
1カテゴリのデータを出力するたびに、8000 件のレコードを毎回全走査していたことが
判明。8000 件で40カテゴリあるので・・・ぞっとするコーディングでした。
で、毎回全件検索しているのは変だと思い、SQLのソート条件をSQLいじっている担当に
聞くと、ソートしてない、とのこと。カテゴリでソートし、データが昇順に並ぶように
しておいて余計なループをまわさないようにした結果が上記秒数になった次第です。

ご協力ありがとうございました。
あまり後進の役に立ちそうも無い内容で恐縮です。

※仕様の不備はそのままにしないで仕様制定した本人に直談判して改善しましょう。
 与えられた仕様だけを満足しちゃうとこんなとんでもないモノができちゃいます。
と再三呼びかけているのですが、効果無し、と・・・


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -