Mic*_*elT 18 .net c# bit-manipulation
在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);
}
Run Code Online (Sandbox Code Playgroud)
现在我看到我的解决方案优于两者struct
和BitConverter
几个滴答.
我认为不安全可能是最快的选择,并接受这个作为答案,但我更喜欢使用托管选项.
Dar*_*rov 16
在C#中将int转换为4字节的最快方法是什么?
使用BitConverter,它的GetBytes重载采用32位整数:
int i = 123;
byte[] buffer = BitConverter.GetBytes(i);
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 15
使用不安全代码的字节*转换是迄今为止最快的:
unsafe static void Main(string[] args) {
int i = 0x12345678;
byte* pi = (byte*)&i;
byte lsb = pi[0];
// etc..
}
Run Code Online (Sandbox Code Playgroud)
这就是BitConverter所做的,这段代码避免了创建数组的成本.
Ily*_*dik 10
我已经研究了将基本类型序列化为字节数组所需的时间.当你已经有一个数组和偏移量来放置你的数据时,我就这样做了.我猜这是一个非常重要的案例,与理论相比,得到一个4字节的数组,因为当你序列化某些东西时,它正是你所需要的.我已经发现什么方法的答案更快取决于你想要序列化的类型.我尝试过几种方法:
m_Bytes[offset] = (byte)(value >> 8)
m_Bytes[offset] = (byte)((i >> 8) & 0xFF)
我跑了所有的测试10毫升.以下是以毫秒为单位的结果
Long Int Short Byte Float Double 1 29 32 31 30 29 34 2 209 233 220 212 208 228 3 63 24 13 8 24 44 4 72 29 14
正如您所看到的那样,对于long和double,不安全的方式要快得多(无符号版本与其签名版本大致相同,因此它们不在表中).对于short/int/float,最快的方法是使用shift进行2/4/4分配.对于字节,最快的显然是简单的赋值.所以关于原始问题 - 分配方式是最好的.这是以最快的方式执行此类功能的示例:
public static void WriteInt(byte[] buffer, int offset, int value)
{
m_BytesInt[offset] = (byte)(value >> 24);
m_BytesInt[offset + 1] = (byte)(value >> 16);
m_BytesInt[offset + 2] = (byte)(value >> 8);
m_BytesInt[offset + 3] = (byte) value;
}
Run Code Online (Sandbox Code Playgroud)
PS测试在x64环境下运行,代码在发布模式下编译为cpu any(运行时为x64).
小智 9
最快的方法是使用包含4个字节的结构.
明显快于BitConverter.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx
有必要的属性.
[StructLayout(LayoutKind.Explicit)]
struct FooUnion
{
[FieldOffset(0)]
public byte byte0;
[FieldOffset(1)]
public byte byte1;
[FieldOffset(2)]
public byte byte2;
[FieldOffset(3)]
public byte byte3;
[FieldOffset(0)]
public int integer;
}
Run Code Online (Sandbox Code Playgroud)
请注意,BitConverter可能不是最快的,如下面的测试所示.
使用BitConverter
该类,特别GetBytes
是带Int32
参数的方法:
var myInt = 123;
var bytes = BitConverter.GetBytes(myInt);
Run Code Online (Sandbox Code Playgroud)
您可以使用它BitConverter.IsLittlEndian
来确定基于CPU架构的字节顺序.
编辑:由于编译器优化,下面的测试不是决定性的.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Explicit)]
struct FooUnion
{
[FieldOffset(0)]
public byte byte0;
[FieldOffset(1)]
public byte byte1;
[FieldOffset(2)]
public byte byte2;
[FieldOffset(3)]
public byte byte3;
[FieldOffset(0)]
public int integer;
}
class Program
{
static void Main(string[] args)
{
testUnion();
testBitConverter();
Stopwatch Timer = new Stopwatch();
Timer.Start();
testUnion();
Timer.Stop();
Console.WriteLine(Timer.ElapsedTicks);
Timer = new Stopwatch();
Timer.Start();
testBitConverter();
Timer.Stop();
Console.WriteLine(Timer.ElapsedTicks);
Console.ReadKey();
}
static void testBitConverter()
{
byte[] UnionBytes;
for (int i = 0; i < 10000; i++)
{
UnionBytes = BitConverter.GetBytes(i);
}
}
static void testUnion()
{
byte[] UnionBytes;
for (int i = 0; i < 10000; i++)
{
FooUnion union = new FooUnion() { integer = i };
UnionBytes = new byte[] { union.byte0, union.byte1, union.byte2, union.byte3 };
}
}
}
}
Run Code Online (Sandbox Code Playgroud)