C#比较包含文本的两个byte []数组为小写

时间:2018-12-12 17:36:15

标签: c# arrays performance

当比较来自两个单独的byte []源(数组/指针)的单个字节值时,如何进行不区分大小写的比较?

我有一个非常大的字节数组,其中包含要通过指针访问的字符串的“干草堆”,并且正在将其与“ needle”模式进行比较,但是当前它仅在存在完全区分大小写的匹配项时才返回。 / p>

是否可以创建一个包含从高到低的值的查找字典,然后在比较循环中使用它,还是有一种更快的方法? (性能方面)

编辑1:

字符串是UTF8编码的。

所需的行为是:比较a,a时返回true;否则,返回true。 A,A;或但是由于UTF8中的“ ​​A”值为65,而“ a”值为97,因此我无法进行不区分大小写的比较。

2 个答案:

答案 0 :(得分:3)

byte数组转换为string,然后进行不区分大小写的比较。像这样:

bool caseInsensitiveByteArrayComparison(byte[] a, byte[] b) {
    string aString = System.Text.Encoding.UTF8.GetString(a);
    string bString = System.Text.Encoding.UTF8.GetString(b);
    return string.Equals(aString, bString, StringComparison.CurrentCultureIgnoreCase);
}

从SO中偷偷偷偷窃取的代码。参见:

  1. How to convert UTF-8 byte[] to string?
  2. Is there a C# case insensitive equals operator?

答案 1 :(得分:3)

大小写ACSII和UTF8代码的字节表示形式的偏移量为32(或hex20),因此您可以将x == byte[x] || x == byte[x+32]与x =大写char值进行比较。

编辑:

假设您实际上只需要处理小写和大写英文字母,则可以按位操作来加快处理速度,因为您可以一次处理8个字节/字符,因为这两个字符之间仅相差3个最高有效位:

'b' & 0b_1101_1111 == 'B' & 0b_1101_1111

因此您可以按8个字节块处理字节数组:

void Main()
{
    byte[] a = "ASDADAGF".Select(x => (byte)(x) ).ToArray();
    byte[] b = "asdAdAGF".Select(x => (byte)(x) ).ToArray();
    bitCompared(a,b).Dump();
}

static bool bitCompared( byte[] b1, byte[]b2)
{
    UInt64 a = BitConverter.ToUInt64(b1, 0); //loop over the index
    UInt64 b = BitConverter.ToUInt64(b2, 0);
    UInt64 mask =0b_1101_1111_1101_1111_1101_1111_1101_1111_1101_1111_1101_1111_1101_1111_1101_1111;
    return (a &= mask) == (b &= mask);
}

afaik还提供了更多的方法来利用SIMD和其他低级别的“黑客”进行优化.....