net core中byte数组如何高效转换为16进制字符串

阿里云教程3个月前发布
28 0 0

在 .NET Core 中,如何把byte[] 转换为 16 进制字符串?你能想到哪些方法?什么方式性能最好?今天和大家分享几种转换方式。

往往在处理字符串性能问题时,第一应该想到的是怎么想办法减少内存分配,怎么优化字符串构建。

下面就通过递进的方式介绍几种实现方式。

1. 使用StringBuilder

在需要做大量字符串拼接的场景中,我们第一就会想到StringBuilder,相比string类型来说StringBuilder更高效。在这个例子中,它通过一次性分配足够的内存,然后配合字节格式化方法AppendFormat进行转换,并逐个追加每个字节的 16 进制表明,以此减少内存分配的开销。

usingSystem;

usingSystem.Text;

publicclass BytesToHexString

{

    publicstatic stringToHexStringStringBuilder(byte[] bytes)

{

      StringBuilderhex = new StringBuilder(bytes.Length* 2);

      foreach(byte b in bytes)

      {

          hex.AppendFormat(“{0:x2}”,b);

      }

      returnhex.ToString();

}

}

下面我们使用Benchmark对ToHexStringStringBuilder方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素分别进行10000次测试,然后进行横向对比。

net core中byte数组如何高效转换为16进制字符串

可以发现这个方法随着数组长度增加整体性能是在下降的。

2. 使用BitConverter

BitConverter 是 .NET中的内置类,它提供了一种简单的方式来转换基础数据类型为字符串。代码超级简洁,但是其本身只能输出固定格式如“0A-BC-99”,有连接符“-”并且字母都是大写,因此只适合简单需求,如果有复杂要求还行额外单独处理。

usingSystem;

publicclass BytesToHexString

{

    publicstatic stringToHexStringBitConverter (byte[] bytes)

    {

        returnBitConverter.ToString(bytes);

    }

}

下面我们再次使用Benchmark对ToHexStringBitConverter方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,进行横向对比。

net core中byte数组如何高效转换为16进制字符串

StringBuilder方式对比,性能得到大幅度提升。

3. 使用 Convert(.NET5+)

Convert是 .NET 中的内置类,Convert.ToHexString是在 .NET 5 中引入的方法,用于将字节数组直接转换为十六进制字符串,改方法设计之初就思考了性能,它在实现上减少了额外的内存分配和操作,因此它比BitConverter.ToString 更高效。但是其本身只能输出固定格式如“0ABC99”,没有连接符“-”并且字母都是大写。

usingSystem;

publicclass BytesToHexString

{

    publicstatic stringToHexStringConvert (byte[] bytes)

    {

        returnConvert.ToHexString(bytes);

    }

}

下面我们再次使用Benchmark对ToHexStringConvert方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

net core中byte数组如何高效转换为16进制字符串

BitConverter方式对比,性能也是大幅度提升。

4. 使用位运算

在将 byte[] 转换为 16 进制字符串时,每个字节会被转化为两个字符。因此,我们需要一个长度为 bytes.Length * 2 的字符数组来存储最终的 16 进制字符串。同时定义字符串hex = “0123456789abcdef”;这个字符串中包含了所有可能的 16 进制字符,接下来遍历循环把每个字节通过位运算分解为2个 4 位的部分(高 4 位和低 4 位),然后通过字符串hex将高4位转为16进制第一个字符,低4位转为第二个字符。以下是一个示例实现:

usingSystem;

publicclass BytesToHexString

{

    publicstatic stringToHexStringBitOperation (byte[] bytes)

    {

        char[] hexChars = new char[bytes.Length* 2];

        conststring hex = “0123456789abcdef”;

        for(int i = 0;i < bytes.Length; i++)

        {

            hexChars[i *2] = hex[bytes[i] >> 4];

            hexChars[i *2+ 1] = hex[bytes[i] & 0x0F];

        }

        returnnew string(hexChars);

    }

}

下面我们再次使用Benchmark对ToHexStringBitOperation方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

net core中byte数组如何高效转换为16进制字符串

虽然和BitConverter相比,性能提升3倍多,但是和Convert方式相比却有所差距。

如果对位运算不是很清楚的,可以留言,后面可以单独出一篇文章讲解一下。

5. 使用 unsafe 代码块(高级)

如果你需要极致的性能,并且可以接受 unsafe 代码,你可以使用指针来操作字节数组。这种方法可以极大地提高性能,但需要注意内存安全问题。

usingSystem;

publicclass BytesToHexString

{

    publicstatic unsafestring ToHexStringUnsafe(byte[] bytes)

    {

        conststring hex = “0123456789ABCDEF”;

        varhexChars = new char[bytes.Length* 2];

        fixed(byte* bytePtr = bytes)

        {

            fixed(char* charPtr = hexChars)

            {

                byte* source = bytePtr;

                char* dest = charPtr;

                for(int i = 0;i < bytes.Length; i++)

                {

                    byteb = source[i];

                    dest[i *2] = hex[b >> 4];

                    dest[i *2+ 1] = hex[b & 0x0F];

                }

            }

        }

        returnnew string(hexChars);

    }

下面我们再次使用Benchmark对ToHexStringBitConverter方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

net core中byte数组如何高效转换为16进制字符串

位运算方式相比,并没有像前面的大幅提升,相差无几。

下面看看5种方法,整体对比情况:

net core中byte数组如何高效转换为16进制字符串

通过上面一系列测试,我们可以得到如下总结:

灵活性:StringBuilder、位操作、unsafe 代码块 > BitConverter、Convert

性能:Convert > unsafe 代码块 > 位操作> BitConverter > StringBuilder

如果只是要把字节数组转化为字符串没有什么要求,那么直接选择官方自带方法Convert.ToHexString;如果对于输出格式有要求,则可以用位操作的方式自己实现个性化需求;当在极端特殊情况下可以思考unsafe 代码块方式。

© 版权声明

相关文章

暂无评论

none
暂无评论...