【问题标题】:What is the fastest way to scan a C# byte[] for two bytes on a 64 bit computer and return the location?在 64 位计算机上扫描 C# byte[] 两个字节并返回位置的最快方法是什么?
【发布时间】:2013-02-19 21:01:30
【问题描述】:

我有一个内存中的byte[],需要找到1310 所在的偏移量。然后我将使用以下内容提取该行:

 String oneLine = Encoding.ASCII.GetString(bytes, 0, max);

在 x64 位计算机上搜索两个字节的最快方法是什么? ..并将其转换为字符串?

除了遍历每个字节,扫描13,然后扫描10,我还能做些什么吗?

// Disclaimer: 
// This is just for my curiosity.  Perhaps I'll gain a better understanding of
// how .NET interfaces with RAM, the CPU instructions related to comparisons, etc.
//  
// I don't suspect a performance problem, but I do suspect a lack of understanding
// (on my part) on how C# does low-level operations.

【问题讨论】:

  • 也许有 - 但您是否测量并发现简单的方法不够足够快
  • 先转换为字符串并执行yourString.IndexOf(Environment.NewLine) 会更快吗?真的很好奇……
  • @PaulSasik 好吧,通常可以通过以对缓存和 CPU 更友好的方式执行相同的操作来获得恒定的加速。有时,这个常数因素很重要。但是,OP 和所有其他要求最快方式的人最好意识到这通常是浪费时间,并且一开始就提出了错误的问题。所以,OP:你为什么还要关心?好奇心(这没什么错)?直觉上明显的方式太慢了?有充分根据(你知道,通过分析和基准测试)知道它比应有的速度慢吗?只有中间那个是一个不好的理由。
  • 最快的方式 - 创建一个非托管 dll 并使用 SCASW - tic01.tic.ec-lyon.fr/~muller/trotek/cours/8086/SCASW.html.en
  • 当然还有其他的:修复数组,将指针转换为ulong*,然后对每个8字节的块使用SWAR来测试它是否包含13。如果是,扫描从该块的开头为 13,10,并且您可以弥补其余部分。这是否更快,谁知道呢。但如果有必要,您可以尝试一下。

标签: c# bytearray micro-optimization


【解决方案1】:

不确定这是否是“最快的方式”,但您可以查看 Boyer-Moore 算法来查找所需值的索引。

看看这个 SO 线程Search longest pattern in byte array in C#

Boyer-Moore 会比线性数组遍历更好,因为它可以根据“针”的长度跳过元素,并且随着“干草堆”变大它会变得更好。 HTH。

【讨论】:

  • 虽然针只有 2 个字节,所以几乎没有跳过
【解决方案2】:

由于您正在寻找一个两字节序列,因此您不必扫描每个字节,只需每隔一个字节即可。如果目标索引包含 13,则查看下一个字节是否为 10。如果目标索引包含 10,则查看前一个字节是否为 13。与线性搜索相比,这应该会将您的扫描时间减少大约一半。

【讨论】:

  • 是的,这似乎是 Boyer-Moore 模式的变体(如果我理解正确的话)
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 2012-08-23
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 2013-08-15
  • 2011-11-04
相关资源
最近更新 更多