Allocating Jagged Array C#

huangapple go评论93阅读模式
英文:

Allocating Jagged Array C#

问题

似乎在C#中分配不规则数组没有很好的方法。分配不规则数组比分配二维数组需要更长的时间。有没有办法绕过这个问题?有没有更好的方法?我希望分配不规则数组的时间与分配二维数组的时间类似。

编辑:为了明确,不规则数组中的每个字节数组都将长度为8。但是二维数组不适用,因为我无法将其传递给我需要传递给的API。我需要使用的API接受一个字节数组的数组。

这需要20秒:

  1. public void CreateHashByte()
  2. {
  3. byte[][] holder = new byte[100000000][];
  4. for (int k = 0; k < 100000000; k++)
  5. {
  6. holder[k] = new byte[8];
  7. }
  8. }

这几乎是瞬间完成的:

  1. public void CreateHashByte2()
  2. {
  3. byte[,] holder = new byte[100000000, 8];
  4. }

编辑2:这很快,大约半秒钟,但它需要我重写API来拆解字节数组。半秒钟似乎仍然是为了分配1GB内存而花费的时间有点长。

  1. public class Hbyte
  2. {
  3. public byte[] data { get; set; } = new byte[8];
  4. }
  5. public Hbyte[] CreateHashByte3()
  6. {
  7. Hbyte[] holder = new Hbyte[100000000];
  8. return holder;
  9. }
英文:

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:

  1. public void CreateHashByte()
  2. {
  3. byte[][] holder = new byte[100000000][];
  4. for (int k = 0; k < 100000000; k++)
  5. {
  6. holder[k] = new byte[8];
  7. }
  8. }

This is almost instantaneous:

  1. public void CreateHashByte2()
  2. {
  3. byte[,] holder = new byte[100000000, 8];
  4. }

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.

  1. public class Hbyte
  2. {
  3. public byte[] data { get; set; } = new byte[8];
  4. }
  5. public Hbyte[] CreateHashByte3()
  6. {
  7. Hbyte[] holder = new Hbyte[100000000];
  8. return holder;
  9. }

答案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

  1. using System.Diagnostics;
  2. const int TestLength = (int)1E8;
  3. var lengths = new int[TestLength];
  4. for (int i = 0; i < TestLength; i++)
  5. {
  6. lengths[i] = i % 10;
  7. }
  8. var timer = new Stopwatch();
  9. // Using C# jagged array
  10. timer.Restart();
  11. var arr1 = new byte[TestLength][];
  12. for (int i = 0; i < TestLength; i++)
  13. {
  14. arr1[i] = new byte[lengths[i]];
  15. }
  16. Console.WriteLine("Jagged Array took " + timer.ElapsedMilliseconds);
  17. // Using 1d array
  18. timer.Restart();
  19. var indices = new long[TestLength]; // You can reuse the lengths array
  20. long currIndex = 0;
  21. for (int i = 0; i < TestLength; i++)
  22. {
  23. indices[i] = currIndex;
  24. currIndex += lengths[i];
  25. }
  26. var arr2 = new byte[currIndex];
  27. Console.WriteLine("1D Array took " + timer.ElapsedMilliseconds);
  28. // To use 1d array:
  29. 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

  1. using System.Diagnostics;
  2. const int TestLength = (int)1E8;
  3. var lengths = new int[TestLength];
  4. for (int i = 0; i < TestLength; i++)
  5. {
  6. lengths[i] = i % 10;
  7. }
  8. var timer = new Stopwatch();
  9. // Using C# jagged array
  10. timer.Restart();
  11. var arr1 = new byte[TestLength][];
  12. for (int i = 0; i < TestLength; i++)
  13. {
  14. arr1[i] = new byte[lengths[i]];
  15. }
  16. Console.WriteLine("Jagged Array took " + timer.ElapsedMilliseconds);
  17. // Using 1d array
  18. timer.Restart();
  19. var indices = new long[TestLength]; // You can reuse the lengths array
  20. long currIndex = 0;
  21. for (int i = 0; i < TestLength; i++)
  22. {
  23. indices[i] = currIndex;
  24. currIndex += lengths[i];
  25. }
  26. var arr2 = new byte[currIndex];
  27. Console.WriteLine("1D Array took " + timer.ElapsedMilliseconds);
  28. // To use 1d array:
  29. var valueAt21 = arr2[indices[2] + 1];

huangapple
  • 本文由 发表于 2023年5月30日 11:50:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76361512.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定