質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

3回答

4753閲覧

大量のCSVファイルのオープンするのが遅い

basscl

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/07/12 08:31

編集2021/07/12 08:49

いつもお世話になっております。
たくさんのCSVファイルを順にオープンして中身を取得するプログラムを作成したいです。
1つのCSVファイルは10行30列程度の小さなものです。
ただし、ファイル数はだいたい3000程度となります。
現在デバッグで下のサンプルコードの4行目のusing (StreamReader readCsvObject = new StreamReader(openFileDialog.FileName))
を実行するだけで8ms程度かかってしまいます。そのため8×3000でこれだけで24秒程度かかってしまいます。
ファイルオープン後の処理の時間に関しては特に問題ありません。

何かほかに早くオープンできる方法はないでしょうか?
よろしくお願いいたします。

for(int i=0;i<3000;i++){ FileName=List[i]; using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.FileName =FileName; using (StreamReader readCsvObject = new StreamReader(openFileDialog.FileName))//この行の時間がかかる { while (!readCsvObject.EndOfStream) { var readCsvLine = readCsvObject.ReadLine(); } } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2021/07/12 08:36

> using (StreamReader readCsvObject = new StreamReader(openFileDialog.FileName)) > を実行するだけで8ms程度かかってしまいます。そのため8×3000でこれだけで24秒程度かかってしまいます。 そこを3000回もループするコードじゃないけども。 (ループしてるのはEndOfStreamとReadLine) どうやって計測したの?
basscl

2021/07/12 08:44

すみません。このコードは一部抜粋で ファイル名の部分が変数でそこを変えながら実行してます。 計測自体はUsingの前後でDatetimeで時間を計測してます。 また、VisualStudioでデバッグモードでの各行の実行時間を確認しながら行いました。
neconekocat

2021/07/12 08:59

片っ端からTaskに放り込んでしまえばいいような
Zuishin

2021/07/12 09:28

実際に一行のファイルを 3000 作ってやってみましたが、1 秒もかかりません。 問題が回答者の手元で実際に再現するコードを作成してください。
Zuishin

2021/07/12 09:29

もちろん、メディアがネットワークドライブとかフロッピーディスクとかいうことはないでしょうね?
neconekocat

2021/07/12 09:33

ちなみにOpenFileDialogは必要なんでしょうか? 必要だとしてもDispose必要ない子なんでusing外したほうがいいと思うんですが。
YAmaGNZ

2021/07/12 10:13

実際に内容を読み込んで処理する時間で8ms以上かかりそうな気がしますが、そちらが無視できるならStreamReaderの作成含めて無視できる時間になるような気がします。
basscl

2021/07/13 00:00

Zuishinさん 現在のテスト環境は普通にデスクトップ上でやってます。 実際は、ネットワーク上のフォルダへのアクセスをするので、もっと遅くなると思います。 Zuishinさん 下の方のコメントにもありましたが、不必要でした。こちらは省きます。
退会済みユーザー

退会済みユーザー

2021/07/13 00:06 編集

> ネットワーク上のフォルダへのアクセスをする 速度に思いきり影響ある部分じゃないですか。そういう重要な情報は質問に必ず記載してください。
basscl

2021/07/13 00:08

radianさん 最終的にはそうなるので、それが原因での速度低下は許容するつもりでした。 現在のデスクトップ上での実験でも遅いので、何か原因がわかればと思っています。 この参照先のCSVファイル読み込みという部分はどうしても変えられないため今の形で行いたいです。
退会済みユーザー

退会済みユーザー

2021/07/13 00:29 編集

gentaroさんの回答のReadAllLinesでやった場合、変化はありましたか?回答に対してきちんとコメント付けて下さい。ディスクIOの影響も当然あるので、そういったデータも出した方が良いかと思われます。 速度改善は細かい最適化の積み重ねなので、ボトルネックの調査が最重要です。
basscl

2021/07/13 00:30

radianさんn 本人の方が追記をしてくれたので、そちらはやってません。 中身の読み込み速度ではなく、オープン部分の速度が現状問題です。
Zuishin

2021/07/13 00:35 編集

ネットワーク越しなら、単純にファイルはネットワーク側で開いて、必要なデータだけをネットワーク越しにやり取りすればいいと思います。 それができない理由がありますか? あるなら、そもそもどのような環境で何をしているのか、状況を詳しく説明してください。
Zuishin

2021/07/13 00:40

どのみち、デスクトップ上で行って 24 秒というのは、このコード以外の条件をこちらで普通に補う限りあり得ません。何か特殊なことをしているか、コードが違うはずです。 コードが違うというのは、これが実際に計測するコードから不要な部分を取り除いたものであるなら、その取り除いた部分に問題がある可能性があるということです。なので、問題の再現する最小限のコードを作り、それで再現することを確認した上で掲載してください。
Zuishin

2021/07/13 00:45

そもそも「この行」で時間がかかっていることはどのようにして確かめたのかも書いてください。 それが間違っている場合、本当は読み込み部分で時間がかかっている可能性もあります。
neconekocat

2021/07/13 01:34

試しにデスクトップのフォルダに10行30列のCSVを3000個作ってforループで1個ずつ開く→中身を読む→閉じるを繰り返したけど3秒も掛かってないですね。開くだけで24秒はプログラムがどうとか以前の話だというのは完全に同意です。
basscl

2021/07/13 01:39

みなさんご意見ありがとうございます。 自分も試しに全く別で、ファイルをオープンするだけのプログラムをデスクトップ上に作ってみましたが、 確かに20秒とかかからないですね… 実際に使用しているプログラムでスレッド処理などしてはいないのですが…
neconekocat

2021/07/13 01:49

ちなみにHDDに置いても時間はあまり変化なしでした。意図的にCPU負荷をかけて使用率100%を維持したら流石に伸びましたけどそれでも20秒はいってないですね。
Zuishin

2021/07/13 01:58

問題を解決したいはずの人になぜか全部スルーされてるけど、質問のコードはそもそもループの中で無駄に OpenFileDialog を操作しているので、なぜこんな意味不明なことをしているかわからない。 「実際はしてない」というのであれば、もう一度書くけど、質問者と回答者がコードを共有できるよう、問題の再現する最小のコードを作って掲載すべき。 と書けば他のを忘れてここだけに反応しそうな気がするが。
gentaro

2021/07/13 14:55

そもそも質問文の論点が間違っている(要旨に沿った最小コードで再現しない)のであれば、この質問は無意味なんですけども、これ以上どうしたいんでしょう。
guest

回答3

0

単純に

File.ReadAllLines

でも使って一気にメモリ上に全行読み込んでから、その内容をループで処理すれば良いんじゃないですかね。


追記

ファイルのオープン・クローズが3000回という話だったのか…。
それは完全にディスクI/Oの速度に依存するので、ファイルをPCIE 4.0のM.2SSDにでも置けば解決するんじゃないですか。

投稿2021/07/12 08:42

編集2021/07/12 08:50
gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ハードの問題だと効果無いかもしれませんが、Parallelクラス で並列処理してみるとか…?
あとは、バックグラウンドで定期的にCSVをDBに取り込むプログラム走らせておいて、処理する時はDBからデータ取るようにするとか、設計面での別のアプローチも考えた方がいいかもしれません。

投稿2021/07/13 00:42

編集2021/07/13 00:49
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

OpenFileDialog が不要な気がしますが・・・
下記ではダメでしょうか?

csharp

1using (StreamReader readCsvObject = StreamReader(FileName)) 2{ 34}

投稿2021/07/12 13:03

odataiki

総合スコア948

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2021/07/12 13:09

それはそうなのですが、質問者さんの言われているStreamReaderの作成部分で時間がかかる(?)という点にはあまり関係がないのではないかと思います。
basscl

2021/07/12 23:53

コメントありがとうございます。 確かに直接関係ありませんでしたが、無駄でした。 いただいた回答のほうがシンプルですのでこちらはそのようにいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問