C#でのメモリ管理について質問です。(もしかしたらメモリ関係ないかもしれませんが...)
今制作しているプログラムで、
while(true)のように永続的なループにおいて、各ループ毎に異なるサイズ(要素数)の1次元配列を確保(生成)する
というロジックがあります。
その際いくつかロジックとして候補がでたのですが、メモリ管理の観点からどれがいいのか悩んでいます。
具体的には以下のようなコードです。恐らくコード上ではしていることは変わらないと思います。
C#
1//パターン1 2 Random random = new Random(); 3 byte[] byteArray = null; 4 5 while (true) 6 { 7 int index = random.Next(1024); 8 9 byteArray = new byte[index]; 10 for (int count = 0; count < index; count++) 11 { 12 byteArray[count] = 0x01; 13 } 14 //byteArrayを使って関数を実行 15 16 if (index == 0) 17 { 18 break; 19 } 20 }
C#
1//パターン2 2 Random random = new Random(); 3 byte[] byteArray2 = new byte[1024]; 4 5 while (true) 6 { 7 int index = random.Next(1024); 8 9 Array.Resize(ref byteArray2, index); 10 for (int count = 0; count < index; count++) 11 { 12 byteArray2[count] = 0x01; 13 } 14 15 //byteArray2を使って関数を実行 16 17 Array.Clear(byteArray2, 0, byteArray2.Length); 18 19 if (index == 0) 20 { 21 break; 22 } 23 }
C#
1//パターン3 2 Random random = new Random(); 3 List<byte> list = new List<byte>(); 4 5 while (true) 6 { 7 int index = random.Next(1024); 8 9 for (int count = 0; count < index; count++) 10 { 11 list.Add(0x01); 12 } 13 14 //list.ToArray()として関数を実行 15 16 list.Clear(); 17 18 if (index == 0) 19 { 20 break; 21 } 22 }
上記の3パターンはこの質問用に組んだコードですが、実際のロジックと変わらない点としては
・配列は1024サイズより上回ることはないが、各ループでサイズは異なる
・コメントアウトで実行する関数に引数として配列が渡されるが、その際初期値の0x00は除かなければならない(※)
・配列はbyteの1次元配列に限定する(※)
・ループを何回繰り返すかわからない上、上記1・2点の理由から、while(true)前に予め配列を確保することはできない
上記の4点です。
このような場合、パターン1~3の中ではメモリ管理の観点としてどれが優れているのでしょうか?
実行速度などもできれば伺いたいのですがまだ自分で試しておらず、自分で確認すべきだと思っていますので、
他の方法も含めてもしご助言いただけますと幸いです。
(C#およびプログラミングを始めて半年と少ししか経っていない初学者ですので、至らぬ点がありましたら申し訳ありません。)
追記(実際にやりたいこと)
実際に制作しているプログラムのロジック(ほぼそのまま)を掲載します。
要件としては
・1024バイト毎にファイルの中身を読みとる
・改行コードが見つかったら、もしくはファイルの最後まで読んだら外部関数を実行
・改行コードがあるまでは外部関数は実行しないが、改行コードまでが1MB以上だった場合はエラーとする(未記載)
以上になります。
上記3点および前述の(※)については要件として変えられないので、「1024バイトごとではなく一気にファイルを読めばいい」「ReadLineを使って」等は実装として不可能です。
C#
1 string filePath = "任意のテキストファイルのフルパス"; 2 byte[] readdata = new byte[1024]; 3 byte[] buffer = new byte[1048576]; //1MB 4 int index = 0; 5 6 FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); 7 8 while (true) 9 { 10 int readByte = fileStream.Read(readdata, 0, 1024); 11 12 if (readByte == 0) 13 { 14 Array.Resize(ref buffer, index + 1); 15 //外部関数 0x00を除いたbyte配列を引数に指定しなければならない 16 break; //ファイルを全て読んだことになるのでwhile(true)から抜ける 17 } 18 19 foreach (byte byte1 in readdata) 20 { 21 if (byte1 == 0x00) 22 { 23 break; 24 } 25 26 if (byte1 == 0x0a) 27 { 28 buffer[index] = byte1; 29 30 if (buffer[index - 1] == 0x0d) 31 { 32 Array.Resize(ref buffer, index + 1); 33 //外部関数 0x00を除いたbyte配列を引数に指定しなければならない 34 index = 0; 35 Array.Clear(buffer, 0, buffer.Length); 36 Array.Resize(ref buffer, 1048576); 37 continue; 38 } 39 40 index++; 41 } 42 43 buffer[index++] = byte1; 44 } 45 }
「Array関数を多用している箇所はインスタンス生成やListでどうにかならないかな?その場合どちらを使う方がいいんだろう?」と思い質問させていただいた次第であります。
ご助言いただけますと幸いです...!
回答4件
あなたの回答
tips
プレビュー