英文:
Allocating Jagged Array C#
问题
似乎在C#中分配不规则数组没有很好的方法。分配不规则数组比分配二维数组需要更长的时间。有没有办法绕过这个问题?有没有更好的方法?我希望分配不规则数组的时间与分配二维数组的时间类似。
编辑:为了明确,不规则数组中的每个字节数组都将长度为8。但是二维数组不适用,因为我无法将其传递给我需要传递给的API。我需要使用的API接受一个字节数组的数组。
这需要20秒:
public void CreateHashByte()
{
byte[][] holder = new byte[100000000][];
for (int k = 0; k < 100000000; k++)
{
holder[k] = new byte[8];
}
}
这几乎是瞬间完成的:
public void CreateHashByte2()
{
byte[,] holder = new byte[100000000, 8];
}
编辑2:这很快,大约半秒钟,但它需要我重写API来拆解字节数组。半秒钟似乎仍然是为了分配1GB内存而花费的时间有点长。
public class Hbyte
{
public byte[] data { get; set; } = new byte[8];
}
public Hbyte[] CreateHashByte3()
{
Hbyte[] holder = new Hbyte[100000000];
return holder;
}
英文:
It seems like there is no good way to allocate a jagged array in C#. It takes several orders of magnitude longer to allocate a jagged array than to allocate a 2D array. Is there any way around this? Is there a better way? I want the allocation of the jagged array to be similar in time the allocation of the 2D array.
Edit: To be clear, every byte array in the jagged array will be length 8. But the 2D array does not work, because I cannot pass it to the API that I need to pass it to. The API I need to use takes an array of byte arrays.
This takes 20 seconds:
public void CreateHashByte()
{
byte[][] holder = new byte[100000000][];
for (int k = 0; k < 100000000; k++)
{
holder[k] = new byte[8];
}
}
This is almost instantaneous:
public void CreateHashByte2()
{
byte[,] holder = new byte[100000000, 8];
}
Edit 2:
This is pretty fast, about a half second, but it requires me to rewrite the API to unwrap the byte array. A half second still seems like a long time to just set aside a GB of memory.
public class Hbyte
{
public byte[] data { get; set; } = new byte[8];
}
public Hbyte[] CreateHashByte3()
{
Hbyte[] holder = new Hbyte[100000000];
return holder;
}
答案1
得分: 1
Using 1D array is faster but you need extra space to manage the indices (or else without it the access would take a long time to know where any element is at).
For my test (ms is the unit):
> Jagged Array took 8418
> 1D Array took 397
using System.Diagnostics;
const int TestLength = (int)1E8;
var lengths = new int[TestLength];
for (int i = 0; i < TestLength; i++)
{
lengths[i] = i % 10;
}
var timer = new Stopwatch();
// Using C# jagged array
timer.Restart();
var arr1 = new byte[TestLength][];
for (int i = 0; i < TestLength; i++)
{
arr1[i] = new byte[lengths[i]];
}
Console.WriteLine("Jagged Array took " + timer.ElapsedMilliseconds);
// Using 1d array
timer.Restart();
var indices = new long[TestLength]; // You can reuse the lengths array
long currIndex = 0;
for (int i = 0; i < TestLength; i++)
{
indices[i] = currIndex;
currIndex += lengths[i];
}
var arr2 = new byte[currIndex];
Console.WriteLine("1D Array took " + timer.ElapsedMilliseconds);
// To use 1d array:
var valueAt21 = arr2[indices[2] + 1];
英文:
Using 1D array is faster but you need extra space to manage the indices (or else without it the access would take a long time to know where any element is at).
For my test (ms is the unit):
> Jagged Array took 8418
> 1D Array took 397
using System.Diagnostics;
const int TestLength = (int)1E8;
var lengths = new int[TestLength];
for (int i = 0; i < TestLength; i++)
{
lengths[i] = i % 10;
}
var timer = new Stopwatch();
// Using C# jagged array
timer.Restart();
var arr1 = new byte[TestLength][];
for (int i = 0; i < TestLength; i++)
{
arr1[i] = new byte[lengths[i]];
}
Console.WriteLine("Jagged Array took " + timer.ElapsedMilliseconds);
// Using 1d array
timer.Restart();
var indices = new long[TestLength]; // You can reuse the lengths array
long currIndex = 0;
for (int i = 0; i < TestLength; i++)
{
indices[i] = currIndex;
currIndex += lengths[i];
}
var arr2 = new byte[currIndex];
Console.WriteLine("1D Array took " + timer.ElapsedMilliseconds);
// To use 1d array:
var valueAt21 = arr2[indices[2] + 1];
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论