【问题标题】:How to fill byte array with junk?如何用垃圾填充字节数组?
【发布时间】:2011-02-28 10:27:47
【问题描述】:

我正在使用这个:

byte[] buffer = new byte[10240];

据我了解,这会初始化填充 0 的 10kb 缓冲区数组。

每次用垃圾数据填充(或初始化)这个数组的最快方法是什么?

我需要使用该数组 >5000 次,并且每次都用不同的垃圾数据填充它,这就是为什么我正在寻找一种快速的方法来做到这一点。数组大小也必须每次都改变。

【问题讨论】:

  • 垃圾数据需要随机吗?还是每次都不一样?
  • 请不要在标题中重复标签(“C#”)。另外,不要使用“csharp”作为标签。它仅用于 4 个问题的事实应该是您不要使用它的线索。

标签: c# arrays bytearray bytebuffer


【解决方案1】:

【讨论】:

    【解决方案2】:

    如果不描述垃圾数据的属性,就不可能回答“最快的方法”。为什么不是全零是有效的垃圾数据?

    也就是说,这是一种用无意义的数字填充数组的快速方法。

    Random r = new Random();
    r.NextBytes(buffer);
    

    如果 Random 对您来说不够快,您也可以考虑实现自己的 Linear congruential generator。它们易于实现且速度快,但不会提供高质量的随机数。 (我不清楚你是否需要这些。)

    【讨论】:

      【解决方案3】:

      数据应该有多垃圾?你的意思是随机的吗?如果是这种情况,只需使用 Random 类。

      【讨论】:

      • 是的,我的意思是随机数据,NextBytes 看起来不错,我一会儿测试一下,谢谢大家的回复。
      【解决方案4】:

      作为另一个需要考虑的选项,Marshall.AllocHGlobal 将分配非托管内存。它不会将内存归零,你会知道发生了什么,所以它非常快。当然,您现在必须使用不安全的代码来处理此内存,如果您需要将其拉入托管空间,您最好使用Random.NextBytes

      【讨论】:

      • 或者打开一个随机图像/文件/可执行文件并简单地将其用作随机数据。
      • 我很确定这是 OP 真正要求的。本质上,在不安全的代码中声明 char* 以指向一个未初始化的内存块,其中填充了最后的内存。
      【解决方案5】:

      如果您对随机数据感到满意,但数据是从随机种子缓冲区创建的,那么您可以执行以下操作:

      public class RandomBufferGenerator
      {
          private readonly Random _random = new Random();
          private readonly byte[] _seedBuffer;
      
          public RandomBufferGenerator(int maxBufferSize)
          {
              _seedBuffer = new byte[maxBufferSize];
      
              _random.NextBytes(_seedBuffer);
          }
      
          public byte[] GenerateBufferFromSeed(int size)
          {
              int randomWindow = _random.Next(0, size);
      
              byte[] buffer = new byte[size];
      
              Buffer.BlockCopy(_seedBuffer, randomWindow, buffer, 0, size - randomWindow);
              Buffer.BlockCopy(_seedBuffer, 0, buffer, size - randomWindow, randomWindow);
      
              return buffer;
          }
      }
      

      我发现它比每次从头开始生成随机缓冲区快大约 60-70 倍。

                    START: From seed buffer.
      00:00:00.009  END  : From seed buffer. (Items = 5,000; Per Second = 500,776.20)
                    START: From scratch.
      00:00:00.604  END  : From scratch. (Items = 5,000; Per Second = 8,276.95) 
      

      更新

      大致思路是创建一次RandomBufferGenerator,然后使用这个实例生成随机缓冲区,例如:

      RandomBufferGenerator generator = new RandomBufferGenerator(MaxBufferSize);
      
      byte[] randomBuffer1 = generator.GenerateBufferFromSeed(10 * 1024);
      byte[] randomBuffer2 = generator.GenerateBufferFromSeed(5 * 1024);
      ...
      

      【讨论】:

      • 我知道要使用该代码,我应该这样做: RandomBufferGenerator bufferGenerator = new RandomBufferGenerator(1024); byte[] 缓冲区 = bufferGenerator.GenerateBufferFromSeed(1024);但是我应该每次都创建一个 RandomBufferGenerator 实例吗?你能给我一个如何使用它的例子吗?谢谢。
      • 是的,创建 RandomBufferGenerator 一次,然后使用此实例生成缓冲区。我已经用一些示例用法更新了答案。
      • 永远不要使用此代码:new Random(DateTime.Now.Millisecond) - 当您简单地使用 new Random 时,它会自动将值从 Environment.TickCount 播种到当前滴答声(100 纳秒)。在您的代码中,在同一毫秒内实例化的所有 Random 将具有相同的种子,因此产生相同的数字,并且在该时间范围内可以创建数千个。这只是不好的做法。
      • @Callum Rogers:该实例旨在被重复使用,因此它很好。虽然你有一个普遍有效的观点,但它不适用于这里。
      • 非常感谢 chibacity,您的代码运行速度比 .NextBytes 快很多
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多