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

わんくま同盟

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

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


(過去ログ 80 を表示中)
■47201 / )  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によって変わる可能性はありますし(実際違うかもしれません、未確認です)、そんなことを意識するべきではないとは私も思うのですが、無視できない現実があるということです。

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

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

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

返信 編集キー/


管理者用

- Child Tree -