在 C# 中将 int 转换为 4 字节的最快方法
在 C# 中将 int 转换为 4 字节的最快方法是什么?
最快的是执行时间而不是开发时间。
我自己的解决方案是这样的代码:
byte[] bytes = new byte[4];
unchecked
{
bytes[0] = (byte)(data >> 24);
bytes[1] = (byte)(data >> 16);
bytes[2] = (byte)(data >> 8);
bytes[3] = (byte)(data);
}
现在我发现我的解决方案比 struct
和 BitConverter
好几个刻度。
我认为不安全可能是最快的选择,并接受它作为答案,但我更愿意使用托管选项。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用不安全代码的 byte* 转换是迄今为止最快的:
这也是 BitConverter 所做的,此代码避免了创建数组的成本。
A byte* cast using unsafe code is by far the fastest:
That's what BitConverter does as well, this code avoids the cost of creating the array.
使用 BitConverter ,它是 GetBytes 重载采用 32 位整数:
Using a BitConverter and it's GetBytes overload that takes a 32 bit integer:
最快的方法是使用包含 4 个字节的结构。
比 BitConverter 快得多。
http://msdn.microsoft.com/en-us/library/system.runtime。 interopservices.structlayoutattribute.aspx
具有必要的属性。
The fastest way is with a struct containing 4 bytes.
Significantly faster than the BitConverter.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx
has the necessary attribute.
我对将基本类型序列化为字节数组所需的时间进行了研究。当您已经有一个数组和要放置数据的偏移量时,我这样做了。我想与理论上获取 4 字节数组相比,这确实是一个重要的情况,因为当您序列化某些内容时,它正是您所需要的。我发现哪种方法更快的答案取决于您想要序列化的类型。我尝试了几种方法:
m_Bytes[offset] = (byte)(value >> 8)
m_Bytes[offset] = (byte)((i >> 8) & 0xFF)
我运行了所有测试 1000 万次。下面是以毫秒为单位的结果
如您所见,对于 long 和 double 来说,不安全的方式要快得多(无符号版本与其签名版本大致相同,因此它们不在表中)。对于短/整数/浮点,最快的方法是带移位的 2/4/4 赋值。对于字节来说,最快的显然是简单的赋值。所以关于原来的问题 - 分配方式是最好的。这是以最快的方式实现此类函数的示例:
PS 测试在 x64 环境上运行,代码在发布模式下编译到 cpu any(运行时为 x64)。
I have done a research on the times needed to serialize a basic type to byte array. I did it for the case when you already have an array and offset where you want to put your data. I guess that's really an important case compared to theoretical get an array of 4 bytes because when you are serializing something then it's exactly what you need. I have figured out that the answer to what method is faster depends on what type you want to serialize. I have tried few methods:
m_Bytes[offset] = (byte)(value >> 8)
m_Bytes[offset] = (byte)((i >> 8) & 0xFF)
I ran all of the test 10 mln times. Below are the results in milliseconds
As you can see the unsafe way is much faster for long and double (unsigned versions are about the same as their signed versions so they are not in the table). For short/int/float the fastest way is the 2/4/4 assignments with shift. For byte the fastest is obviously the simple assignment. So regarding the original question - the assignment way is the best. This is the example of such a function in a fastest way:
P.S. The tests were run on x64 environment with code compiled to cpu any (which was x64 on run) in release mode.
请注意,如下面的测试所示,BitConverter 可能不是最快的。
使用
BitConverter
类,特别是GetBytes
方法,采用Int32
参数:您可以使用
BitConverter.IsLittlEndian
根据 CPU 架构确定字节顺序。编辑:由于编译器优化,下面的测试并不是结论性的。
Note the BitConverter may not be the fastest as the test below shows.
Use the
BitConverter
class, specifically theGetBytes
method that takes anInt32
parameter:You can use
BitConverter.IsLittlEndian
to determine the byte order based on the CPU architecture.EDIT: The test below isn't conclusive due to compiler optimisations.
正如这里的许多人似乎在争论 BitConverter 是否比专用的 struct 更好。基于 BCL 源代码,
BitConverter.GetBytes()
如下所示:从我的角度来看,这比对显式结构进行 1 个整数 + 4 个字节赋值更干净,而且速度更快。
As many in here seem to argue about if
BitConverter
is beter than a dedicatedstruct
. Based on BCL source code theBitConverter.GetBytes()
looks like this:Which from my point of view is more clean and seems faster than making 1 integer + 4 byte assignments to a explicit struct as this one.
在我的机器上平均约为 2770 毫秒,而
平均约为 4510 毫秒。
Averages around 2770ms on my machine while
Averages around 4510ms.
我认为这可能是 C# 中最快的方法..(字节数组初始化为 int 流的 4 倍/ int32
I think this might be the fastest way in C#.. (with byte array initialized to 4x the int stream w/ int32
联合是将整数拆分为字节的最快方法。下面是一个完整的程序,其中 C# 优化器无法优化字节拆分操作,因为每个字节都会被求和并打印出总和。
我的笔记本电脑上的计时为Union 为 419 毫秒,BitConverter 为 461 毫秒。然而,速度增益要大得多。
该方法用在一个开源高性能算法HPCsharp库中,其中Union方法为基数排序提供了很好的性能提升。
Union 速度更快,因为它不执行按位掩码和位移,而只是从 4 字节整数中读取正确的字节。
Union is the fastest way of splitting an integer into bytes. Below is a complete program in which the C# optimizer can't optimize the byte splitting operation out, because each byte is summed and the sum is printed out.
The timings on my laptop are 419 milliseconds for the Union and 461 milliseconds for the BitConverter. The speed gain, however, is much greater.
This method is used in an open source high-performance algorithms HPCsharp library, where the Union method provides a nice performance boost for the Radix Sort.
Union is faster because it performs no bitwise masking and no bit-shift, but simply reads the proper byte out of the 4-byte integer.