ソース配列にnullableがないことが保証されていると仮定して、 nullableの配列(たとえばbyte?[]
、)をnullableでない配列(たとえば、)にコピーする効率的な方法はありますか(もしあれば、例外をスローしても問題ありません)?byte[]
明らかに、インデックスをループして、各要素を個別にコピーできます。
これは動作しません。ArrayTypeMismatchException
コンパイルされますが、実行時にスローされます。
byte?[] sourceNullable = new byte?[]{1,2,3};
byte[] destNonNullable = new byte[3];
Array.Copy(sourceNullable,destNonNullable,3);
これは機能しますが、「より良い」ものを探しています
for(int i=0;i<3;i++) {
destNonNullable[i] = sourceNullable[i] ?? 0;
}
私は答えを喜んで受け入れます:明示的なループの何が問題なのですか? そして、なぜこれを最適化するのに時間を無駄にしているのですか? :)
編集:Linq style を使用してみCast<>()
ましたが、はるかに遅いことがわかりました。以下の私のコードからの時間の要約:
for ループ = 585 ミリ秒
Linq キャスト = 3626 ミリ秒
入力image
ファイルは、null のセクションで満たされたスパース配列です。
uint rowsize = 16;
Stopwatch sw = new Stopwatch();
sw.Start();
for (UInt32 address = start & 0xFFFFFFF0; address <= last; address += rowsize)
{
Int32 imageOffset = (Int32)(address - start);
Int32 maxRowLen = (int)rowsize;
if (maxRowLen + imageOffset > image.Length) maxRowLen = (image.Length - imageOffset);
if (maxRowLen == 0) throw new Exception("this should not happen");
int ptr = 0;
while (ptr < maxRowLen)
{
while (ptr < maxRowLen && image[imageOffset + ptr] == null) ptr++;
int startOffset = ptr;
while (ptr < maxRowLen && image[imageOffset + ptr] != null) ptr++;
int stopOffset = ptr;
if (startOffset < maxRowLen)
{
#if false
int n = stopOffset - startOffset;
byte[] subdata = new byte[n];
for (int i = 0; i < n; i++)
{
subdata[i] = image[imageOffset + startOffset + i] ?? 0;
}
#else
byte[] subdata = image.Skip(imageOffset + startOffset).Take(stopOffset - startOffset).Cast<byte>().ToArray();
#endif
IntelHexRecord rec = new IntelHexRecord((uint)(address + startOffset), subdata);
records.Add(rec);
}
}
}
sw.Stop();
Console.WriteLine("elapsed: {0} ms", sw.ElapsedMilliseconds);