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

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

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

Re[28]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法


(過去ログ 142 を表示中)

[トピック内 69 記事 (1 - 20 表示)]  << 0 | 1 | 2 | 3 >>

■83253 / inTopicNo.1)  大量のテキストファイルをマルチスレッドで高速に読み込む方法
  
□投稿者/ 金尾 (1回)-(2017/03/15(Wed) 20:40:08)

分類:[.NET 全般] 


10MBのテキストファイルが1万個ほどあり、
これを読み込んで、その内容をまとめたデータを作成したいと考えています。

普通にReadlineで読み込んでいくと
10分くらいかかってしまいます。
ただ、CPU使用率を見ていると、シングルスレッドで動作しているため、
10%程度しか使用していないため
マルチスレッドにすれば10倍近くに高速化できると思います。

それで、以下のように10個ずつファイルを読み込んで
マルチスレッドでプログラムを作成したみたのですが
どうも、
Encoding.UTF8.GetString(bs).Split(CChar(vbCrLf))
というコマンドをマルチスレッドにしてもほとんど速くなりません。

恐らく、メモリがボトルネックになり、
同時に複数の配列を処理できていないのではないかと思うのですが、
タスクマネージャやリソースモニターでは
メモリの使用量は確認できても、メモリの転送速度はモニターできないので
それが正しいかどうか分かりません。

どうすれば、もっと高速化することができますか?


以下がコードです。



Sub code


For i = 1 to 1000

Dim fs As New FileStream(Path(i), FileMode.Open, FileAccess.Read)
Dim bs1(file_size - 1) As Byte
fs.Read(bs1, 0, file_size)
fs.Close()
MultiTask_in01 = New Task(AddressOf Data_in, bs01)
MultiTask_in01.Start()

fs = New FileStream(Path(i + 1), FileMode.Open, FileAccess.Read)
Dim bs2(file_size - 1) As Byte
fs.Read(bs2, 0, file_size)
fs.Close()
MultiTask_in02 = New Task(AddressOf Data_in, bs02)
MultiTask_in02.Start()

'・・・・

fs = New FileStream(Path(i + 9), FileMode.Open, FileAccess.Read)
Dim bs10(file_size - 1) As Byte
fs.Read(bs10, 0, file_size)
fs.Close()
MultiTask_in10 = New Task(AddressOf Data_in, bs10)
MultiTask_in10.Start()


next i


End Sub


Private Sub Data_in(ByVal bs0() As Byte)


Dim bs() As Byte = bs0.Clone

Dim str() As String = Encoding.UTF8.GetString(bs).Split(CChar(vbCrLf))

'ここにデータをまとめるための処理を書く。

End Sub





引用返信 編集キー/
■83254 / inTopicNo.2)  Re[1]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 金尾 (2回)-(2017/03/15(Wed) 20:41:35)


Waitが抜けていました


For i = 1 to 1000

 Dim fs As New FileStream(Path(i), FileMode.Open, FileAccess.Read)
 Dim bs1(file_size - 1) As Byte
 fs.Read(bs1, 0, file_size)
 fs.Close()
 MultiTask_in01 = New Task(AddressOf Data_in, bs01)
 MultiTask_in01.Start()

 fs = New FileStream(Path(i + 1), FileMode.Open, FileAccess.Read)
 Dim bs2(file_size - 1) As Byte
 fs.Read(bs2, 0, file_size)
 fs.Close()
 MultiTask_in02 = New Task(AddressOf Data_in, bs02)
 MultiTask_in02.Start()

	'・・・・

fs = New FileStream(Path(i + 9), FileMode.Open, FileAccess.Read)
 Dim bs10(file_size - 1) As Byte
 fs.Read(bs10, 0, file_size)
 fs.Close()
 MultiTask_in10 = New Task(AddressOf Data_in, bs10)
 MultiTask_in10.Start()


        MultiTask_in01.Wait()
        MultiTask_in02.Wait()
        MultiTask_in03.Wait()
        MultiTask_in04.Wait()
        MultiTask_in05.Wait()
        MultiTask_in06.Wait()
        MultiTask_in07.Wait()
        MultiTask_in08.Wait()
        MultiTask_in09.Wait()
        MultiTask_in10.Wait()

next i

引用返信 編集キー/
■83255 / inTopicNo.3)  Re[2]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 774RR (488回)-(2017/03/15(Wed) 20:59:11)
# コードは見てない

ファイルの読み込みは I/O bound つまりはハードディスクや SSD の性能で決まってしまうので
> 10%程度しか使用していないため
は当たり前(CPU はハードディスクの応答を待っているので 10% 以上つかいようがない)んでないかな。

マルチスレッドで複数のファイルを読むとシーク時間がかかる分逆効果、かもしれない。

高速化するにはまず測定。何が遅いのかを確かめてから。

引用返信 編集キー/
■83256 / inTopicNo.4)  Re[3]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 金尾 (4回)-(2017/03/15(Wed) 21:03:17)
No83255 (774RR さん) に返信


SSDを使っていますが、
まったくここはボトルネックになっていないことが分かっています。
SSDからファイルをバイナリ配列に読み込む時間よりも20倍くらい
バイナリ配列からストリング配列に変換する方が時間がかかります。

そのため、マルチスレッド化すれば高速化できると考えました

引用返信 編集キー/
■83257 / inTopicNo.5)  Re[1]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 魔界の仮面弁士 (1186回)-(2017/03/15(Wed) 21:10:15)
2017/03/15(Wed) 21:20:52 編集(投稿者)

No83253 (金尾 さん) に返信
> 10MBのテキストファイルが1万個ほどあり、

トータルで 100GB ぐらいですね。


> 普通にReadlineで読み込んでいくと
> 10分くらいかかってしまいます。

どのようなストレージを利用していますか?

シーケンシャルリードが 64MB/sec 程度の 5400 rpm な HDD と仮定した場合、
100GB のデータ転送にかかる時間は、約 26 分換算。

シーケンシャルリードが 100MB/sec 程度の 7200 rpm な HDD と仮定した場合、
100GB のデータ転送にかかる時間は、約 17 分換算。

シーケンシャルリードが 210 MB/sec 程度の SSD と仮定した場合、
100GB のデータ転送にかかる時間は、約 8 分換算。

ランダムアクセスの場合は、処理にもよりますが、概ねこの倍ぐらいでしょうか。


> マルチスレッドにすれば10倍近くに高速化できると思います。

1 万個のファイルが、10 台のSSD に分散配置されているなら、
各ドライブごとに専任のタスクを割り当てれば早くなりそうです。

しかし同一の物理ドライブ上にある場合は、マルチスレッドにすることで、
むしろ遅くなってしまう可能性が高そうです。
引用返信 編集キー/
■83258 / inTopicNo.6)  Re[4]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 魔界の仮面弁士 (1187回)-(2017/03/15(Wed) 21:38:10)
2017/03/15(Wed) 21:39:35 編集(投稿者)

No83256 (金尾 さん) に返信
> SSDを使っていますが、

SSD なのですね。

定常状態のパフォーマンスは、実機で測定してみないとわかりませんが、
下記のような測定結果がありました。


2012年9月「HDD,SSD,USBメモリのアクセス速度比較実験」
https://hikaku.cman.jp/hdd_rpm/

2015年「SSD 徹底比較」
http://www.ssd-fan.com/pcmark8/ssd_bm.php

2017年冬「2.5インチSSD性能」
http://pssection9.com/archives/2-5-sata3-ssd-spec.html


今時の SSD だと、500MB/sec 程度出せそうですね。

仮に 500MB/sec だったとしても、100GB の連続転送は、
 100GB ÷ 500MB/sec = 200 秒 ≒ 3 分
程度を要します。

「10分くらい」の処理を「10倍」にするには、
約 1.5GB/sec の転送速度が必要なので、
SSD から NVMe に換装しないと無理かも知れません。
引用返信 編集キー/
■83259 / inTopicNo.7)  Re[2]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 金尾 (6回)-(2017/03/15(Wed) 21:44:28)
確かに、100GBのファイルをコピーしようとすると10分くらいかかってしまいます。

しかし、VB.NETで
Dim str() As String = Encoding.UTF8.GetString(bs).Split(CChar(vbCrLf))

の部分をコメントアウトし、
バイト配列→ストリング配列の処理を行わなければ
1分くらいで処理が完了するのですが
これはなぜでしょうか?

配列が空になっているのではないかと思い
if bs(filesize -1000)= 0 then msgbox ""
みたいなのも入れてみましたが
配列にはデータが格納できているみたいです

引用返信 編集キー/
■83260 / inTopicNo.8)  Re[1]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 魔界の仮面弁士 (1188回)-(2017/03/15(Wed) 21:56:43)
No83253 (金尾 さん) に返信
No83253 (金尾 さん) に返信
> For i = 1 to 1000
>  Dim fs As New FileStream(Path(i), FileMode.Open, FileAccess.Read)
>  Dim bs1(file_size - 1) As Byte
ファイル数が多いので、配列を都度作成するのではなく、
確保済みの配列を使いまわすようにした方が良いでしょう。

100MB もの巨大な配列を、毎回廃棄&確保し続けるのは効率が悪いです。

Dim a = Now
Dim size_100MB = (100 * 1024 * 1024) - 1
For i = 1 To 1000
 Dim bs1(size_100MB) As Byte
 bs1(0) = i And &HFF
Next
Dim b = Now
MsgBox((b - a).TotalSeconds)


上記は、100MB の配列確保を 1000 回行っていますが、
当方環境では約 4 秒という時間を要しました。

しかし bs1配列の宣言をループの外に出した場合、
その 4 秒間で 20億回のループが可能でした。
引用返信 編集キー/
■83261 / inTopicNo.9)  Re[3]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 金尾 (8回)-(2017/03/15(Wed) 22:22:09)
すいません、上記のコードは分かりやすく書き換えたものです
もちろん配列の定義はForの外で行っています
また、Forの外と中でも比較を行いましたが
それ以外に律速する要素が大きいため計算時間はほとんど差異が見られませんでした。

ところで、
マルチスレッド読み込みを行うプログラムを使って
SSDとHDDで計算時間の比較を行いましたが
全く同じ結果が得られました
やはりストレージ速度がボトルネックにはなっていないようです

メモリがボトルネックになっているかどうかは
どのようにすれば調べられますでしょうか?
 
引用返信 編集キー/
■83262 / inTopicNo.10)  Re[3]: 大量のテキストファイル
□投稿者/ Azulean (793回)-(2017/03/15(Wed) 22:52:00)
2017/03/15(Wed) 22:54:07 編集(投稿者)

No83261 (金尾 さん) に返信
> メモリがボトルネックになっているかどうかは
> どのようにすれば調べられますでしょうか?

ストレージの影響ではないと仮定しても、メモリのスピードの影響だと言い切るのは弱いと思いますね。
(仮にメモリのスピードの影響だとしても、それはマルチスレッドにしたところで改善しないので、打つ手なしなので建設的ではありません…)
というより、たいていはストレージよりもメモリの方が速いはずなので、「メモリ(のアクセススピード)がボトルネックである」という仮定をしたり、調べたりすることがありません。

巨大な配列の確保・解放を繰り返した場合、スワップが発生する、ページフォールトが起きるといった意味ではメモリ・ストレージ間のデータ転送待ちになることはよくあります。
それが起きている場合、タスクマネージャーの詳細タブでページフォールトの数が勢いよく上がるはずなので、それで観測できるかもしれません。
それが要因の場合は、メモリの確保・解放を繰り返さない、それでも発生するならメモリ確保量・処理量を見直すってことになると思います。


No83259 (金尾 さん) に返信
> しかし、VB.NETで
> Dim str() As String = Encoding.UTF8.GetString(bs).Split(CChar(vbCrLf))
>
> の部分をコメントアウトし、
> バイト配列→ストリング配列の処理を行わなければ
> 1分くらいで処理が完了するのですが
> これはなぜでしょうか?

「バイト列を UTF-8 と解釈して String にする処理」と「改行ごとに区切った String 配列を生み出す処理」が時間かかるってことでは。
前者が遅いのか、後者が遅いのかは、Split なくしたコードを実験すれば切り分けられるかと。


ところで、Split は配列を生み出すので、そういう意味だとループの中で確保・解放を助長していることになります。
10MB のテキストというと、かなりの分量でしょうから、それを 1 万ファイルとなると、メモリの確保・解放による処理のロスは大きいかもしれませんね。
引用返信 編集キー/
■83263 / inTopicNo.11)  Re[4]: 大量のテキストファイル
□投稿者/ 金尾 (10回)-(2017/03/15(Wed) 23:04:38)
「バイト列を UTF-8 と解釈して String にする処理」と「改行ごとに区切った String 配列を生み出す処理」
では、後者の方が数倍時間がかかります。

>10MB のテキストというと、かなりの分量でしょうから、それを 1 万ファイル
一万ファイル全て読み込ませるのではなく
10ファイルずつあるいは30ファイルずつ読み込ませています

引用返信 編集キー/
■83264 / inTopicNo.12)  Re[5]: 大量のテキストファイル
□投稿者/ Azulean (794回)-(2017/03/15(Wed) 23:17:18)
No83263 (金尾 さん) に返信
> 「バイト列を UTF-8 と解釈して String にする処理」と「改行ごとに区切った String 配列を生み出す処理」
> では、後者の方が数倍時間がかかります。

配列の要素数と、それぞれの要素(String) 1 つあたりの文字数のイメージを共有してみてください。


> >10MB のテキストというと、かなりの分量でしょうから、それを 1 万ファイル
> 一万ファイル全て読み込ませるのではなく
> 10ファイルずつあるいは30ファイルずつ読み込ませています

それは理解していますが、「ずつ」とはいえ、ボタンを押すか、プログラムをスタートさせるかで、「連続的に 1 万ファイルの分量を処理するなら、メモリの確保・解放の回数が非常に多いでしょう」ということを言いたかったのです。


もっとも、配列の数が多く、かつそれの確保・解放が支配的なのか、文字列の走査が支配的なのかはなんとも言えませんが。
引用返信 編集キー/
■83265 / inTopicNo.13)  Re[6]: 大量のテキストファイル
□投稿者/ 金尾 (12回)-(2017/03/15(Wed) 23:28:22)
ありがとうございます。

> 配列の要素数と、それぞれの要素(String) 1 つあたりの文字数のイメージを共有してみてください。

これはどのようにすれば良いのでしょうか?

> もっとも、配列の数が多く、かつそれの確保・解放が支配的なのか、文字列の走査が支配的なのかはなんとも言えませんが。

もし、後者が支配的なのだとすると
マルチスレッドで速度向上が見られるはずですが
それが見られないので
前者が支配的なのではないかと考えました。


引用返信 編集キー/
■83266 / inTopicNo.14)  Re[7]: 大量のテキストファイル
□投稿者/ Azulean (795回)-(2017/03/15(Wed) 23:37:37)
2017/03/15(Wed) 23:40:00 編集(投稿者)

No83265 (金尾 さん) に返信
>>配列の要素数と、それぞれの要素(String) 1 つあたりの文字数のイメージを共有してみてください。
>
> これはどのようにすれば良いのでしょうか?

デバッグしていくつかのファイルで配列の数を見るとか、配列の中の文字数を調べてみていって、何文字くらいになっているか、数量を適当に量ってください。
統一的な手法はないので、周りの人が処理量を把握できるように、あなたが考えて決めてください。


>>もっとも、配列の数が多く、かつそれの確保・解放が支配的なのか、文字列の走査が支配的なのかはなんとも言えませんが。
(略)
> 前者が支配的なのではないかと考えました。

その仮定が正しいのであれば、「今のやり方=Split した結果を欲する」が崩せない限り、時間短縮は難しいかと思います。
本当に、「改行ごとにばらした String 配列」じゃないといけないのか、考え直すのも一手でしょう。
引用返信 編集キー/
■83268 / inTopicNo.15)  Re[3]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 魔界の仮面弁士 (1189回)-(2017/03/16(Thu) 04:43:55)
No83259 (金尾 さん) に返信
> CChar(vbCrLf)
これは ControlChars.Cr と同義ですが、本当にそれで良いのでしょうか。
CR + LF ではなく、CR で分割していることになりますが…。


> Dim str() As String = Encoding.UTF8.GetString(bs).Split(CChar(vbCrLf))

パフォーマンスの検証とするならば、このようにまとめて書くのではなく、
・GetString メソッドの実行時間
・Split メソッドの実行時間
のように、各メソッドごとに調べるべきかと思います。

処理的には Split の方が時間がかかりそうですね。
以下、当方環境での実験結果。


'検証用の 10MB のダミー配列
Dim bin10MB(10 * 1024 * 1024 - 1) As Byte
For n = 0 To bin10MB.GetUpperBound(0)
bin10MB(n) = &H2A
Next
For n = 10 To bin10MB.GetUpperBound(0) Step 255
bin10MB(n) = 13
Next

'GetString および Split の速度調査
Dim a = Now
Dim str10MB = System.Text.Encoding.UTF8.GetString(bin10MB)
Dim b = Now
Dim aryLines = str10MB.Split(ControlChars.Cr)
Dim c = Now

Console.WriteLine((b - a).TotalSeconds) '0.0110029 〜 0.0139725
Console.WriteLine((c - b).TotalSeconds) '0.0369978 〜 0.0409782

上記は単一回の実行ですが、ループ処理で複数回連続で呼び出す場合は、
前回のループ処理で使われていた String 配列(≠Byte 配列)が破棄される分のコストも
もしかしたら足かせになってくるかもしれません。



No83261 (金尾 さん) に返信
> すいません、上記のコードは分かりやすく書き換えたものです
処理は単純化してもらった方が良いですが、実際のコードとあまりに異なっていると、
第三者が試したときに結果がブレてしまい、むしろ分かりにくくなる恐れがありそうです。


ところで、最初の質問にあった ReadLine だったものを並列化したいという話だけなら、
パフォーマンスはさておき、ReadLine のままで並列化できるようにも思うのですが、
何故 ReadLine を使わない方法に変更されたのでしょうか?

全バイナリの一括読み取りなら File.ReadAllBytes の方がスマートに書けそうですし、
テキストファイルから「内容をまとめたデータ」を作成するための処理というのが、
行単位の順次読み取りで済むのであれば、わざわざ自前で Split して配列化せずとも、
File.ReadLines メソッドで十分であるような気もするのですが。

もしかして、FileAccess 等の制御をしたいが故に FileStream を使っているということなのでしょうか。
それとも、System.IO.File の静的メソッドだと、エラーになったとか、極端に遅くなるなどの
何かしらの弊害があって現状のコードになったのでしょうか。
引用返信 編集キー/
■83269 / inTopicNo.16)  Re[1]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ ニートプログラマ (1回)-(2017/03/16(Thu) 08:55:10)
興味がある内容なので注目しています。えっとまずは
本当にCPUを100%使えるのかを確認したらいかが
でしょう??

https://www.axfc.net/u/3787171.zip

32bitのx86尽瘁バイナリexeで何もしないスレッドを
4つ作成します。当方のCore2 Quadマシンではきっ
ちり全コアが100%の使用率になります。
各スレッドはフレッド終了フラグをテストループして
いるだけです。

C#で同様のプログラムを作成してまずはきっちり
CPUを使いきれるのかを確認し、その後実際の処理を
記述してどの処理がCPUを遊ばせるのかを追及する
手法もあるかと思います。
C#は詳しくないですがスレッドの管理のために
クリティカルセッションを頻繁に使っていると
スレッド化してもCPUの使用率は上がりません。
あ、スレッド化の意味が無いってことではない
です。



引用返信 編集キー/
■83271 / inTopicNo.17)  Re[4]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ なちゃ (181回)-(2017/03/16(Thu) 09:36:14)
No83256 (金尾 さん) に返信
> ■No83255 (774RR さん) に返信
>
>
> SSDを使っていますが、
> まったくここはボトルネックになっていないことが分かっています。
> SSDからファイルをバイナリ配列に読み込む時間よりも20倍くらい
> バイナリ配列からストリング配列に変換する方が時間がかかります。
>
> そのため、マルチスレッド化すれば高速化できると考えました

これってトータルどのくらいのファイルサイズで確認しました?
また実行環境のメモリ量はどのくらいでしょうか?
こういうシンプルな処理でディスクが全く影響しないとか、後であったようにHDDにしても全く変わらないとかはほぼ考えられないので、単にキャッシュから読んだだけでは?という気がします。

引用返信 編集キー/
■83272 / inTopicNo.18)  Re[2]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ 金尾 (13回)-(2017/03/16(Thu) 09:39:54)
Azuleanさん

> 配列の中の文字数を調べてみていって、何文字くらいになっているか、数量を適当に量ってください。
もちろん数量のはかり方は分かるのですが
そのはかった数量をどのようにして共有したら良いのか分からないのですが
Split関数では生成した配列をそのままコピーされますので
前回使用した配列のサイズなどは流用できないと思うのですが
どのようにすれば良いですか?

魔界の仮面弁士さん

> 何故 ReadLine を使わない方法に変更されたのでしょうか?

これは
魔界の仮面弁士さん自身も仰っているように
> しかし同一の物理ドライブ上にある場合は、マルチスレッドにすることで、
> むしろ遅くなってしまう可能性が高そうです。

これが起きるためです。
SSDだとそれほど違いはないですがHDDでReadlineのコードをマルチスレッド化すると
3倍くらい速度が落ちる結果が得られました。
ストレージからデータをメモリに読み込む部分だけは
シングルスレッドにしておき、
読み込んだデータをストリング配列にする部分だけをマルチスレッド化しないと
逆に速度が低下してしまいます。

> の一括読み取りなら File.ReadAllBytes の方がスマートに書けそうですし
実際にはファイルの全てを読み込む必要はなく、後半の8割程度のみが必要なためです
File.ReadAllBytes だと、ファイルの一部のみを読み込むことができません。


ニートプログラマさん

> がある内容なので注目しています。えっとまずは
> 本当にCPUを100%使えるのかを確認したらいかが
> でしょう??


マルチスレッドはこれまでに何度も作成していますので
CPU使用率が100%になるのは確認でてきます



引用返信 編集キー/
■83273 / inTopicNo.19)  Re[3]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
□投稿者/ なちゃ (182回)-(2017/03/16(Thu) 10:25:27)
マルチスレッド化して高速化できる可能性があるとすれば、読み込みとその後の処理の並列化です。
何倍も変わることはまずあり得ないですが。

この場合、読み込んだ後の処理だけを並列化しても意味がありません。
読み込みと処理を、並列化する必要があります。
前の読み込みデータを処理しながら、次の読み込みを並行して行うということです。
引用返信 編集キー/
■83274 / inTopicNo.20)  Re[3]: 大量のテキストファイルをマルチスレッドで高速に読み込む方法
 
□投稿者/ 魔界の仮面弁士 (1190回)-(2017/03/16(Thu) 10:40:34)
2017/03/16(Thu) 10:46:28 編集(投稿者)

No83272 (金尾 さん) に返信
> ストレージからデータをメモリに読み込む部分だけは
> シングルスレッドにしておき、
ストレージからの読み取りは、どうあっても 10 分間を要すると思っていたのですが、

> 実際にはファイルの全てを読み込む必要はなく、後半の8割程度のみが必要なためです
を実施していたために、実際にはそれより短い時間で処理できる目算ということなのですね。

# 情報の後出し(というか、提示のサンプルと実際の処理との乖離)が他にもありそうな予感…。


> Split関数では生成した配列をそのままコピーされますので
> 前回使用した配列のサイズなどは流用できないと思うのですが
> どのようにすれば良いですか?

「何を目的として Split を使っているのか」を説明していただいていないため
今回の事象に適合できるか分からないですが、元のコードの
 Encoding.UTF8.GetString(bs).Split(c)
だと、「元のバイナリ」「それを文字列化したもの」「さらにそれを分割したもの」
が必要なので、元データの約 3 倍のメモリを消費することになると思います。

現状のこの、
  UTF-8 Binary → String → 改行単位の String()
という変換処理を見直して、
  UTF-8 Binary → 改行文字の位置のみを列挙 → 必要な部分だけ随時 String 化
という手順にすれば、消費メモリを 3 割程度削減できる気がします。


データ量が多いので、手順が多少増えたとしても、メモリの破棄と再確保の
頻度と総量を減らす方が、結果的に高速化に貢献するものと予想。
(本当に高速化するかは、検証してみないと分からないですけれども)
引用返信 編集キー/

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

管理者用

- Child Tree -