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

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

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

Re[15]: CSVファイル入出力時の速度向上方法について [1]


(過去ログ 80 を表示中)

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

■47075 / inTopicNo.21)  Re[11]: CSVファイル入出力時の速度向上方法について
  
□投稿者/ こあら (78回)-(2010/02/18(Thu) 01:56:04)
No47047 (みきぬ さん) に返信
> ■No47041 (こあら さん) に返信
> ただ今回の話では、元質問者から具体的なコードが提示されています。
> わざわざ別のやり方で結果を示す理由がわからなかったのです。
> # VB6 の確認環境がないから、とかならわかるんだけど
>
> さらに言うと、私から見たこあらさんのやりかたは、元質問者の方法を「わざわざ遅くしている」ようにも見えました。
> こあらさんのやり方で雲泥の差が出ても、それが元質問者の方法でもそのような結果になるかというと、関係がないと思うのです。
> # ADODB.Stream を知らない(CSV ファイルを DB のように扱ってるのかなあ、くらいの理解)し、
> # 確認できる環境も持ってないので、このへんは単なる勘ですが


疑問が分かりました。こちらの状況を説明すると、
・VB6の環境がない
・VBScriptならADODB.Streamのファイルコピースクリプトを持っていた
・ADODB.StreamもFileSystemObject.TextStreamもMemoryStreamだから似たような性能でしょ?
・ActiveXならVB6からでもVBScriptからでも呼び出しコストは大差ないんじゃない?
です。

つまり、こちらでチャチャッと試せて質問者さんの環境と似たような結果になりそうだという判断でした。
少し配慮が足りなかったかもしれません。すみませんでした。



せっかくなので懲りずにTextStreamに書き直してみました。都合によりやはりVBScriptで。
*---
Option Explicit
'On Error Resume Next

dim fso, istream, ostream, i, s

s = Now()

Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set istream = fso.OpenTextFile("C:\temp\input.csv")
Set ostream = fso.CreateTextFile("C:\temp\output.csv")

For i = 1 to 100
istream.SkipLine
Next

'Do While not istream.AtEndOfStream
' ostream.WriteLine istream.ReadLine
'Loop
'↑↓どちらかを有効にして速度を計ってください
'ostream.Write istream.ReadAll

istream.Close
ostream.Close

Set istream = Nothing
Set ostream = Nothing
Set fso = Nothing

Msgbox FormatDateTime(Now() - s)
---*

引用返信 編集キー/
■47172 / inTopicNo.22)  Re[11]: CSVファイル入出力時の速度向上方法について
□投稿者/ おたすけ ひでやん (1回)-(2010/02/19(Fri) 22:13:11)
No47047 (みきぬ さん) に返信
> ■No47041 (こあら さん) に返信
>>>>VBScriptでADODB.Streamを使って「一行ずつ」と「残り一括」を比較したら、雲泥の差でしたよ。
>>
> >>この結果から何が導かれるのか分からないので、補足を希望します。
>>
>>「同じ出力ファイルを作るのに、手続きによって処理時間が異なる」です。
>>
> やり方によってはそういう場合もあるということはわかります。
>
> ただ今回の話では、元質問者から具体的なコードが提示されています。
> わざわざ別のやり方で結果を示す理由がわからなかったのです。
> # VB6 の確認環境がないから、とかならわかるんだけど
>
> さらに言うと、私から見たこあらさんのやりかたは、元質問者の方法を「わざわざ遅くしている」ようにも見えました。
> こあらさんのやり方で雲泥の差が出ても、それが元質問者の方法でもそのような結果になるかというと、関係がないと思うのです。
> # ADODB.Stream を知らない(CSV ファイルを DB のように扱ってるのかなあ、くらいの理解)し、
> # 確認できる環境も持ってないので、このへんは単なる勘ですが

割り込み失礼します。
私も、上記考えと一緒です。streemを使ったほうが早いです。
ちなみに、vb.net でstreemを使わずに、30万件のCSVを出力すると約 7Sかかりました。
streemを使用して入力および出力を30万件行った結果、400msで済みます。
なお、streemを使用した場合で、たとえば内部配列に複数レコード読み込んで、一気に読み込んだ分を書き込んでも
入出力時間は変わりませんでした。(下記ソースにて実施)
これは、お使いの環境によって変わってくると思いますけど、ちなみに実施した環境は、
   
   processer Intel(R) Core(TM)2 CPU 6600 @2.40GHz(2 CPUs)
   mem: 2046MB RAM

   (まあ、どこにでもある普通のpcです。)

参考までに使用したソースを掲載しておきます。
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim FileAccHd As New CommonClassLibrary1.FileAcc
Dim seq As Long = 0
Dim starttime As DateTime = DateTime.Now
Dim StiMillisecond As Integer = starttime.Millisecond


Dim RecCnt As Integer
Dim TTLRecCnt As Long = 0
Dim BuffNum As Integer = TextBox5.Text
STreemFileOpen("testData01.csv")
WriteFileOpen("testData01wr.csv")
RecCnt = 999
While RecCnt > 0
RecCnt = FileRead("testData01.csv", BuffNum)
Writes("testData01wr.csv")
TTLRecCnt = TTLRecCnt + RecCnt
End While
STreemFileClose()
WriteFileClose()
Dim endtime As DateTime = DateTime.Now
Dim EdiMillisecond As Integer = endtime.Millisecond
TextBox4.Text = TTLRecCnt '処理した件数
TextBox2.Text = starttime & ":" & StiMillisecond '開始時間
TextBox3.Text = endtime & ":" & EdiMillisecond '終了時間

End Sub
Private pRecords() As String
Private pSr As System.IO.StreamReader
Public Sub STreemFileOpen(ByVal FileName As String)
Dim sr As New System.IO.StreamReader(FileName, _
System.Text.Encoding.GetEncoding(932))
pSr = sr
End Sub
Public ReadOnly Property FileRead(ByVal FileName As String, ByVal BuffNum As Integer)
Get
Dim i As Long = 0
Dim record As String
pRecords = Nothing
ReDim Preserve pRecords(BuffNum)
'複数のレコードを一気によみバッファへ格納
While pSr.Peek() > -1
If i <= pRecords.Length - 1 Then
record = pSr.ReadLine()
pRecords(i) = record
i += 1
Else
Exit While
End If
End While
Return i
End Get
End Property
Public Sub STreemFileClose()
'閉じる
pSr.Close()
End Sub
Private pSrWrite As System.IO.StreamWriter
Public Sub WriteFileOpen(ByVal FileName)
Dim SrWrite As New System.IO.StreamWriter(FileName, False, System.Text.Encoding.GetEncoding("shift_jis"))
pSrWrite = SrWrite
End Sub
Private pFileNum As Integer
'複数のレコードをファイルへ書きこむ
Public Sub Writes(ByVal FileName)
Dim FileNum As Integer = FreeFile()
Dim idx As Integer
Dim Line As String = ""
For idx = 0 To pRecords.Length - 1
Try
pSrWrite.Write(pRecords(idx))
Catch ex As Exception
WriteFileClose()
Exit For
End Try
Next
End Sub
Public Sub WriteFileClose()
pSrWrite.Close()
End Sub

使用したデータ内容

Data1,xxxxxxxxxxxxxxxxxxxxxxxx,0,yyyyyyyy
Data1,xxxxxxxxxxxxxxxxxxxxxxxx,1,yyyyyyyy
Data1,xxxxxxxxxxxxxxxxxxxxxxxx,2,yyyyyyyy
 |
 |
 30万件
引用返信 編集キー/
■47179 / inTopicNo.23)  Re[12]: CSVファイル入出力時の速度向上方法について
□投稿者/ なちゃ (398回)-(2010/02/20(Sat) 00:46:11)
こういうベンチって正確に実行するのはそれなりに難しいですよ。

※例えば、レコード単位で読み書きと、1MB単位で読み書きの速度を計測した時、双方読み込みファイルのキャッシュは消えた状態で実行しているか?

もし読み込みファイルがキャッシュにのっていれば、実質的にHDDアクセスの際のシークや回転待ちがゼロになってしまって、
・単なるシーケンシャルな書き込み
・デコード+エンコード+単なるシーケンシャルな書き込み
の比較にしかならない可能性があります。

当然、本当のレコード単位や1MB単位(本当のHDDアクセス単位はまた違いますが)でのランダム読み書きとは全くパフォーマンスが違ってきます。


あと、1MBサイズとかでファイルに書き込むと、ライトスルーな動作になって(遅延書き込みが無効になって)、読み込みと交互に実行すると余計パフォーマンスが悪くなる気もします。
※1MBを一気にFileStreamに書き出さずに、遅延書き込みが有効になるくらいのもう少し小さいサイズで繰り返して書き込めばこれは防げると思いますが。

逆にレコード単位だと、デフォルトでは4Kか8Kか単位でファイル書き込みになり、このサイズだと遅延書き込みが効くので、読み込みと交互だとパフォーマンスが上がったりという可能性もある気がします。
※こっちはFileStreamのバッファサイズを遅延書き込みできる範囲内で大きくするともう少し効率よくなりそうです。


引用返信 編集キー/
■47199 / inTopicNo.24)  Re[13]: CSVファイル入出力時の速度向上方法について
□投稿者/ れい (880回)-(2010/02/21(Sun) 03:12:00)
No47179 (なちゃ さん) に返信

なちゃさんが何を言っているのかよくわかりません。

> こういうベンチって正確に実行するのはそれなりに難しいですよ。

ええ。
それは皆さん当然知っていると思いますよ。
だからこそMSも風評被害を防ぐため、「完全に再現する情報」がなければ公開するな、といっているわけで。

> ※例えば、レコード単位で読み書きと、1MB単位で読み書きの速度を計測した時、双方読み込みファイルのキャッシュは消えた状態で実行しているか?
>略
> 当然、本当のレコード単位や1MB単位(本当のHDDアクセス単位はまた違いますが)でのランダム読み書きとは全くパフォーマンスが違ってきます。

本当のレコード単位や1MB単位のアクセスの時間が知りたいわけではありません。
「アルゴリズムを変える」ことで「実際に使う際の速度を早くする」と言うお題に対して、
ベンチマークで知見が得られればいいわけです。

「実際に使う際」の状況は質問者からは殆どなにも示されていないので、「普通」や「常識的状況」を想定するしかありません。
ならば「適当にキャッシュに載った状態」で測るのが妥当です。

で、実際にどのくらいキャッシュに載っているのかは幅があり、ベンチの時にも幅があります。
他にもさまざまな要因で幅が出て、その幅に応じて測定結果の誤差がきまります。
実際にはその誤差は測定できないので「見積もる」しかないですが。
アルゴリズム間の差が、見積もられた誤差よりも大きければお題に対して有効な解決案であると言えます。

その「見積もられた誤差」が妥当かどうかは重要ですが、
ベンチマークが正確かどうかはどうでもいいことです。

なので、みきぬさんもこあらさんも、見積もりが正しいかどうかを話題にしています。
みきぬさんはADODB.Streamを使うやり方では「関係ない」=「系統誤差が大きすぎる」と疑問を呈し、
こあらさんは「大差ないんじゃない?」と誤差が小さいだろうと述べているわけです。

> あと、1MBサイズとかでファイルに書き込むと、ライトスルーな動作になって(遅延書き込みが無効になって)、読み込みと交互に実行すると余計パフォーマンスが悪くなる気もします。
> ※1MBを一気にFileStreamに書き出さずに、遅延書き込みが有効になるくらいのもう少し小さいサイズで繰り返して書き込めばこれは防げると思いますが。
>
> 逆にレコード単位だと、デフォルトでは4Kか8Kか単位でファイル書き込みになり、このサイズだと遅延書き込みが効くので、読み込みと交互だとパフォーマンスが上がったりという可能性もある気がします。
> ※こっちはFileStreamのバッファサイズを遅延書き込みできる範囲内で大きくするともう少し効率よくなりそうです。

そういった場合があるかもしれませんが。
よほど特殊なケースでないかぎり、それを考えて作るのは間違いであろうと思います。

まとめて書き込んで遅延書き込みが無効になって遅くなる、というような問題は
OSなりドライバなりが対応すべき事柄でしょう。

それを考えなければパフォーマンスが足りないような状況なら、
そもそもプラットフォームの選定を間違えています。

#バッファのサイズはどのくらいが適切か、という話ならいろいろ考慮すべき点はあり、話題は尽きないでしょうが。


No47075 (こあら さん) に返信
> ■No47047 (みきぬ さん) に返信
>>■No47041 (こあら さん) に返信
>>ただ今回の話では、元質問者から具体的なコードが提示されています。
>>わざわざ別のやり方で結果を示す理由がわからなかったのです。
>># VB6 の確認環境がないから、とかならわかるんだけど
>>
>>さらに言うと、私から見たこあらさんのやりかたは、元質問者の方法を「わざわざ遅くしている」ようにも見えました。
>>こあらさんのやり方で雲泥の差が出ても、それが元質問者の方法でもそのような結果になるかというと、関係がないと思うのです。
>># ADODB.Stream を知らない(CSV ファイルを DB のように扱ってるのかなあ、くらいの理解)し、
>># 確認できる環境も持ってないので、このへんは単なる勘ですが
>
>
> 疑問が分かりました。こちらの状況を説明すると、
> ・VB6の環境がない
> ・VBScriptならADODB.Streamのファイルコピースクリプトを持っていた
> ・ADODB.StreamもFileSystemObject.TextStreamもMemoryStreamだから似たような性能でしょ?
> ・ActiveXならVB6からでもVBScriptからでも呼び出しコストは大差ないんじゃない?
> です。

私も最初はこあらさんのスクリプトでも十分実証になる=系統誤差が十分小さいと思ったのですが、
いまはそうは思っていません。

.Netでやってみたベンチだと、HDD以外の部分でもかなり時間を消費しているようでした。

「何も考えずに組んでも9割がHDDアクセスだ」というような状況ならActiveXでもVB6でもVBScriptでも、
その呼び出し法がなんであってもいいでしょうが、
メモリ内の処理でかなりの時間を食っていたわけで、話が変わります。

ADODB.StreamとFileSystemObject.TextStreamではずいぶん違ってもおかしくありません。
ADODB.Streamの中身は知りませんが、もしかすると最初に全読みするStreamかもしれませんし。
ずいぶん違う可能性があるので、あまり「関係ない」ということですね。

引用返信 編集キー/
■47201 / inTopicNo.25)  Re[14]: CSVファイル入出力時の速度向上方法について
□投稿者/ なちゃ (399回)-(2010/02/21(Sun) 10:23:57)
No47199 (れい さん) に返信
> ■No47179 (なちゃ さん) に返信
>
> なちゃさんが何を言っているのかよくわかりません。
>
>>こういうベンチって正確に実行するのはそれなりに難しいですよ。
>
> ええ。
> それは皆さん当然知っていると思いますよ。
> だからこそMSも風評被害を防ぐため、「完全に再現する情報」がなければ公開するな、といっているわけで。

まず最初に、ちょっと私の書き方がよくなかったです。
正確にとか本当のという書き方をしている部分は、現実的な動作に近い条件で(ベンチを)動作させることは、というような感覚だと思ってください。
※本当に正確な(厳密な)という観点も別途ありますが、正確さや厳密さにこだわって言ったのではありません。

で、もっと正直に言うと、私が上の書き込みをしたのは、■No47172 などで書かれている、
400msと7sなどの数値が、あまりに現実離れしているように思えたからです。
※これに関してはキャッシュの問題ではないでしょうが、キャッシュの話はベンチと現実に差が出やすい例として分かりやすいものをあげたものです。

そしてもうひとつ、なんとなく全体的に読んだときに、レコード単位で読み書きするよりもバイナリで読み書きした方が絶対的に速い、という思い込みを招きそうな流れに見えたからです。
※これは普通に考えると当たり前ではありますが、条件によってそうとも言い切れない場合もある、ということも一応言っておきたかったという感じです。

>>当然、本当のレコード単位や1MB単位(本当のHDDアクセス単位はまた違いますが)でのランダム読み書きとは全くパフォーマンスが違ってきます。
>
> 本当のレコード単位や1MB単位のアクセスの時間が知りたいわけではありません。
> 「アルゴリズムを変える」ことで「実際に使う際の速度を早くする」と言うお題に対して、
> ベンチマークで知見が得られればいいわけです。

上に書きましたが、私も本当のレコード単位や1MB単位のアクセスの時間を計測する、という意図で書いたのではありませんでした(書き方が悪かったです)。
現実的には、ほぼキャッシュに載っていない状態〜完全にキャッシュに載っている状態まで様々な状況が考えられますが、一般にディスク読み込みや書き込みのパフォーマンスに関する話題では、それほどキャッシュに載っていない状況を想定するのが一般的には多いのではないかと思います。
今回の話題でその感覚が当てはまるかは別ですが、この話の流れを呼んだ人の中には、暗黙的にそういう想定をして読んでしまう人が結構いるのではないか、という思いがあります。

> 「実際に使う際」の状況は質問者からは殆どなにも示されていないので、「普通」や「常識的状況」を想定するしかありません。
> ならば「適当にキャッシュに載った状態」で測るのが妥当です。
>
> で、実際にどのくらいキャッシュに載っているのかは幅があり、ベンチの時にも幅があります。
> 他にもさまざまな要因で幅が出て、その幅に応じて測定結果の誤差がきまります。
> 実際にはその誤差は測定できないので「見積もる」しかないですが。
> アルゴリズム間の差が、見積もられた誤差よりも大きければお題に対して有効な解決案であると言えます。
>
> その「見積もられた誤差」が妥当かどうかは重要ですが、
> ベンチマークが正確かどうかはどうでもいいことです。

ベンチが正確かはどうでもいいですが、キャッシュの状況がどうかというのは結果に大幅な影響を与えますので、誤差で済むレベルではなく、それがどういう状況かが分からない結果はちょっと危険に思います。

というか、実際動かした結果が、キャッシュ状況によって逆転するようなレベルで影響がある時、そのキャッシュ状況がどういう状態でベンチマークしたかというのは重要な話で、そのあたり誰も触れていないと、なんとなく思い込みを招きそうに思いました。
※逆転するかどうかはまた環境や条件によりますが、あり得るということです。

> なので、みきぬさんもこあらさんも、見積もりが正しいかどうかを話題にしています。
> みきぬさんはADODB.Streamを使うやり方では「関係ない」=「系統誤差が大きすぎる」と疑問を呈し、
> こあらさんは「大差ないんじゃない?」と誤差が小さいだろうと述べているわけです。

私は、キャッシュや遅延書き込みの状況による影響が、現実的に大きな結果の違いを引き起こす可能性もあるだろう、と思っています。

>>(バッファサイズと遅延書き込みの話、省略)
>
> そういった場合があるかもしれませんが。
> よほど特殊なケースでないかぎり、それを考えて作るのは間違いであろうと思います。
>
> まとめて書き込んで遅延書き込みが無効になって遅くなる、というような問題は
> OSなりドライバなりが対応すべき事柄でしょう。

OS環境によって変わりますし、私もこれを意識して作るのがいいとはあまり思えないのですが、現実に
1MB単位で書き込むコードと、256KB以下単位とかで書き込むコードで比べてみれば、無視できない場合があることはすぐに分かります。
もちろん、遅延書き込みの場合はコードが完了しても書き込みは完了していませんが。

これに、シーケンシャルな書き込みではなく同じディスクへの読み込みも関わってくると、結果に大きな影響が出る可能性があります(この影響は、読み込みファイルのキャッシュ状況で大きく変わるはずです)。

※1MBや256KBというのはOSによって変わる可能性はありますし(実際違うかもしれません、未確認です)、そんなことを意識するべきではないとは私も思うのですが、無視できない現実があるということです。

> それを考えなければパフォーマンスが足りないような状況なら、
> そもそもプラットフォームの選定を間違えています。
>
> #バッファのサイズはどのくらいが適切か、という話ならいろいろ考慮すべき点はあり、話題は尽きないでしょうが。

単にこういう現実がある、このような動作が結果に大きな影響を与え得る、ということをいいたかっただけで、それ以上のことを言うつもりはありません。

あと、もちろん、そんなことは分かっているという人は多くいるでしょうが、この話の流れを読んだときに、常にバイナリでまとめて読み書きするのが絶対的に速い、という短絡的な結論を下す人がいるのではないかという懸念があったので、念のためにこういう話も書いておきたかった、という感じです。
※もちろん、一般論としてはそれは正しいと思っていますが。

引用返信 編集キー/
■47202 / inTopicNo.26)  Re[14]: CSVファイル入出力時の速度向上方法について
□投稿者/ おたすけ ひでやん (2回)-(2010/02/21(Sun) 11:02:55)
No47199 (れい さん) に返信
> ■No47179 (なちゃ さん) に返信
>
> なちゃさんが何を言っているのかよくわかりません。
>
>>こういうベンチって正確に実行するのはそれなりに難しいですよ。
>
> ええ。
> それは皆さん当然知っていると思いますよ。
> だからこそMSも風評被害を防ぐため、「完全に再現する情報」がなければ公開するな、といっているわけで。
>
>>※例えば、レコード単位で読み書きと、1MB単位で読み書きの速度を計測した時、双方読み込みファイルのキャッシュは消えた状態で実行しているか?
> >略
>>当然、本当のレコード単位や1MB単位(本当のHDDアクセス単位はまた違いますが)でのランダム読み書きとは全くパフォーマンスが違ってきます。
>
> 本当のレコード単位や1MB単位のアクセスの時間が知りたいわけではありません。
> 「アルゴリズムを変える」ことで「実際に使う際の速度を早くする」と言うお題に対して、
> ベンチマークで知見が得られればいいわけです。
>
> 「実際に使う際」の状況は質問者からは殆どなにも示されていないので、「普通」や「常識的状況」を想定するしかありません。
> ならば「適当にキャッシュに載った状態」で測るのが妥当です。
>
> で、実際にどのくらいキャッシュに載っているのかは幅があり、ベンチの時にも幅があります。
> 他にもさまざまな要因で幅が出て、その幅に応じて測定結果の誤差がきまります。
> 実際にはその誤差は測定できないので「見積もる」しかないですが。
> アルゴリズム間の差が、見積もられた誤差よりも大きければお題に対して有効な解決案であると言えます。
>
> その「見積もられた誤差」が妥当かどうかは重要ですが、
> ベンチマークが正確かどうかはどうでもいいことです。
>
> なので、みきぬさんもこあらさんも、見積もりが正しいかどうかを話題にしています。
> みきぬさんはADODB.Streamを使うやり方では「関係ない」=「系統誤差が大きすぎる」と疑問を呈し、
> こあらさんは「大差ないんじゃない?」と誤差が小さいだろうと述べているわけです。
>
>>あと、1MBサイズとかでファイルに書き込むと、ライトスルーな動作になって(遅延書き込みが無効になって)、読み込みと交互に実行すると余計パフォーマンスが悪くなる気もします。
>>※1MBを一気にFileStreamに書き出さずに、遅延書き込みが有効になるくらいのもう少し小さいサイズで繰り返して書き込めばこれは防げると思いますが。
>>
>>逆にレコード単位だと、デフォルトでは4Kか8Kか単位でファイル書き込みになり、このサイズだと遅延書き込みが効くので、読み込みと交互だとパフォーマンスが上がったりという可能性もある気がします。
>>※こっちはFileStreamのバッファサイズを遅延書き込みできる範囲内で大きくするともう少し効率よくなりそうです。
>
> そういった場合があるかもしれませんが。
> よほど特殊なケースでないかぎり、それを考えて作るのは間違いであろうと思います。
>
> まとめて書き込んで遅延書き込みが無効になって遅くなる、というような問題は
> OSなりドライバなりが対応すべき事柄でしょう。
>
> それを考えなければパフォーマンスが足りないような状況なら、
> そもそもプラットフォームの選定を間違えています。
>
> #バッファのサイズはどのくらいが適切か、という話ならいろいろ考慮すべき点はあり、話題は尽きないでしょうが。
>
>
> ■No47075 (こあら さん) に返信
>>■No47047 (みきぬ さん) に返信
> >>■No47041 (こあら さん) に返信
> >>ただ今回の話では、元質問者から具体的なコードが提示されています。
> >>わざわざ別のやり方で結果を示す理由がわからなかったのです。
> >># VB6 の確認環境がないから、とかならわかるんだけど
> >>
> >>さらに言うと、私から見たこあらさんのやりかたは、元質問者の方法を「わざわざ遅くしている」ようにも見えました。
> >>こあらさんのやり方で雲泥の差が出ても、それが元質問者の方法でもそのような結果になるかというと、関係がないと思うのです。
> >># ADODB.Stream を知らない(CSV ファイルを DB のように扱ってるのかなあ、くらいの理解)し、
> >># 確認できる環境も持ってないので、このへんは単なる勘ですが
>>
>>
>>疑問が分かりました。こちらの状況を説明すると、
>>・VB6の環境がない
>>・VBScriptならADODB.Streamのファイルコピースクリプトを持っていた
>>・ADODB.StreamもFileSystemObject.TextStreamもMemoryStreamだから似たような性能でしょ?
>>・ActiveXならVB6からでもVBScriptからでも呼び出しコストは大差ないんじゃない?
>>です。
>
> 私も最初はこあらさんのスクリプトでも十分実証になる=系統誤差が十分小さいと思ったのですが、
> いまはそうは思っていません。
>
> .Netでやってみたベンチだと、HDD以外の部分でもかなり時間を消費しているようでした。
>
> 「何も考えずに組んでも9割がHDDアクセスだ」というような状況ならActiveXでもVB6でもVBScriptでも、
> その呼び出し法がなんであってもいいでしょうが、
> メモリ内の処理でかなりの時間を食っていたわけで、話が変わります。
>
> ADODB.StreamとFileSystemObject.TextStreamではずいぶん違ってもおかしくありません。
> ADODB.Streamの中身は知りませんが、もしかすると最初に全読みするStreamかもしれませんし。
> ずいぶん違う可能性があるので、あまり「関係ない」ということですね。
>

割り込み失礼します。

私も、れいさんの考えにほぼ同じなのですが、いずれにしてもstremを使用することにより性能は変わってくると思います。
どれぐらい変わるかは、やはりvb6の環境にて実施しないとなんとも言えないと思います。


> .Netでやってみたベンチだと、HDD以外の部分でもかなり時間を消費しているようでした。
>
 確かに、.netの動作方式を考えると消費することが考えられますね!


>
> ADODB.Streamの中身は知りませんが、もしかすると最初に全読みするStreamかもしれませんし。

 私の環境でもvb6の環境は無いのでなんとも言えませんが、vb6自体もストリームが使えることは認識しております。
 ストリーム使用において、オープンするところ(定義するところ?)で入出力バッファサイズの指定があると思います。
(vb.net環境ではあります。たぶんそんなに変わってないと思います)

 バッファサイズが指定が確認できましたら、あとはファイルのサイズ、使用環境のメモリサイズ、処理のプライオリティ
 その他バックグラウンドで動作しているアプリケーションが使用しているメモリなどの情報を元に最適なバッファサイズ
 を検討してみてはと思いまが如何でしょうか?−>みち さんへ

みちさんへ
  また、操作するファイルが10〜20万件ということなので、大きさも10M〜30Mぐらいなのかな?
  (レコードサイズに依存してくるので解りませんけど..)
  その規模のファイルでしたらプログラムロジックでゴチャゴチャと考えるよりもファイルの入出力制御をストリームに
  委ねたほうが効率いいと思います。
  この扱うファイルが、何Gbyteとかになると根本的に方式を検討することもあると思いますが!
  (ファイルをある大きさに区切って処理するようにするとか..)
  多分、掲載のロジックでのレスポンスは数秒かな?


> ずいぶん違う可能性があるので、あまり「関係ない」ということですね。
 少なくとも、ストリームを使用するのと、しないのとでは性能の誤差が目に見えてはっきりしていることが分かったので
 試た価値はあったと思いますので^^

追伸
 掲載したソースに誤りが、入力と書き込みロジックを以下のソースに置き換えてください。

Public ReadOnly Property FileRead(ByVal FileName As String, ByVal BuffNum As Integer)
Get
Dim i As Long = 0
Dim record As String
pRecords = Nothing
ReDim Preserve pRecords(BuffNum)
'内容を一行ずつ読み込む
While pSr.Peek() > -1
If i <= pRecords.Length - 1 Then
record = pSr.ReadLine()
pRecords(i) = record
i += 1
Else
Exit While
End If
End While
If i < BuffNum Then
ReDim Preserve pRecords(i - 1)
End If
Return i
End Get
End Property
'複数のレコードをファイルへ書きこむ
Public Sub Writes(ByVal FileName)
Dim FileNum As Integer = FreeFile()
Dim idx As Integer
Dim Line As String = ""
For idx = 0 To pRecords.Length - 1
Try
pSrWrite.Write(pRecords(idx) & vbCrLf)

Catch ex As Exception
WriteFileClose()
Exit For
End Try
Next
End Sub


引用返信 編集キー/
■47203 / inTopicNo.27)  Re[15]: CSVファイル入出力時の速度向上方法について
□投稿者/ なちゃ (400回)-(2010/02/21(Sun) 11:29:18)
あーすいません、根本的に誤解を与えてしまっていたかも知れないので一応。

アルゴリズム的な観点でバイナリで処理する方が速いことを否定しようとしたのではないです。

キャッシュや遅延書き込みの影響で、本来速いはずの処理方式が現実のアプリでは遅くなってしまうこともあり得るという事、
ベンチマークよりも実際のアプリの方がそういう事が起こりやすかったりもする(キャッシュを特に制御していないベンチマークなら特に)、
といった辺りの事も念のため言っておきたかった、というか。
※当事者に対してというより、一般的な話として

引用返信 編集キー/
■47204 / inTopicNo.28)  Re[15]: CSVファイル入出力時の速度向上方法について
□投稿者/ おたすけ ひでやん (3回)-(2010/02/21(Sun) 14:33:03)
No47201 (なちゃ さん) に返信
> ■No47199 (れい さん) に返信
>>■No47179 (なちゃ さん) に返信
>>
>>なちゃさんが何を言っているのかよくわかりません。
>>
> >>こういうベンチって正確に実行するのはそれなりに難しいですよ。
>>
>>ええ。
>>それは皆さん当然知っていると思いますよ。
>>だからこそMSも風評被害を防ぐため、「完全に再現する情報」がなければ公開するな、といっているわけで。
>
> まず最初に、ちょっと私の書き方がよくなかったです。
> 正確にとか本当のという書き方をしている部分は、現実的な動作に近い条件で(ベンチを)動作させることは、というような感覚だと思ってください。
> ※本当に正確な(厳密な)という観点も別途ありますが、正確さや厳密さにこだわって言ったのではありません。
>
> で、もっと正直に言うと、私が上の書き込みをしたのは、■No47172 などで書かれている、
> 400msと7sなどの数値が、あまりに現実離れしているように思えたからです。
> ※これに関してはキャッシュの問題ではないでしょうが、キャッシュの話はベンチと現実に差が出やすい例として分かりやすいものをあげたものです。
>
キャッシュの問題です。
 ちなみに、7sはキャッシュを使用しなかった場合の実測値(当環境にての)です。
 私も少し、勘違いしてました。申し訳ありません。
 質問のVB6のソースをよく見ると、ストリームで処理しているようです。
 
 ただ、入出力バッファサイズの指定は見えないので規定値が有効となると思いますが、いくつになるかは疑問です。
 ひょっとすると、このあたりの数値を操作するだけで比較的性能は向上すると思いますが..

 ただ、このソースにおいて入出力はあくまでも行単位で行っていると思いますのでその方式は変えない方向で検討すべきではないでしょうか?
 (レコード単位で処理することに何か別の要因があるようにも思えます。深読みかもしれません。)






引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

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

管理者用

- Child Tree -