English 中文(简体)
C#中以最快的方式将 in改为4
原标题:Fastest way to convert int to 4 bytes in C#

在C#中,什么是最快的转换到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);
}

现在,我看到,我的解决方案通过两条标准,超越了<条码>、<条码>和<条码>。

我认为,不安全可能是最快的选择,并接受作为答案,但我倾向于采用管理的办法。

最佳回答

采用不安全守则的沥青是最快的:

    unsafe static void Main(string[] args) {
        int i = 0x12345678;
        byte* pi = (byte*)&i;
        byte lsb = pi[0];  
        // etc..
    }

根据比托埃特人所做的那样,该法典避免了创建阵列的成本。

问题回答

我已经对将基本类型的子体序列化所需的时间进行了研究。 如果你已经拥有一个阵列,我就这样做了。 我猜测,与理论相比,一个真正重要的案件有4个 by子,因为当你将一些事情编成册时,这完全是你所需要的。 我已经指出,对什么方法越快的答案取决于你想要将哪类方法分类。 我尝试的方法很少:

  1. Unsafe reference with an additional buffer overrun check
  2. GetBytes + consequent Buffer.BulkCopy (This is essentially the same as 1 plus overhead)
  3. Direct assignment with shift ( m_Bytes[offset] = (byte)(value >> 8)
  4. Direct assignment with shift and bitwise & 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          

你们可以看到,不安全的道路要长、两倍得多(签字文本与签字文本大致相同,因此不在表格中)。 短期/int/float最快的是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;
    }

P.S. 测试是在X64环境中进行的,其编码是按释放方式编成的(运行时为x64)。

www.un.org/Depts/DGACM/index_spanish.htm 请注意,BitConverter可能并非最快的,因为以下测试显示:。

使用http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx” rel=“noreferer”BitConver< 专栏:: 代码>GetBytes, 采用<>><>>>>>>>>>>>><<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>

var myInt = 123;
var bytes = BitConverter.GetBytes(myInt);

您可使用BitConverter.IsLittlEndian ,以确定基于CPU结构的特令。


www.un.org/Depts/DGACM/index_spanish.htm EDIT: 下面的测试是编辑选择成像的结果。


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 };

            }
        }
    }
}

这里的许多人似乎认为,<代码>是否可行。 BiConverter 小于专用struct。 根据《巴塞尔公约》源代码:<代码> BiConverter.GetBytes()。

public static unsafe byte[] GetBytes(int value)
{
    byte[] buffer = new byte[4];
    fixed (byte* bufferRef = buffer)
    {
        *((int*)bufferRef) = value;
    }
    return buffer;
}

从我的观点看,这种安排更清洁,似乎比把1个愤怒+4个按部就班的任务变成一个明确的结构更快。

[StructLayout(LayoutKind.Explicit)]
struct IntByte
{
  [FieldOffset(0)]
  public int IntVal;
  [FieldOffset(0)]
  public byte Byte0;
  [FieldOffset(1)]
  public byte Byte1;
  [FieldOffset(2)]
  public byte Byte2;
  [FieldOffset(3)]
  public byte Byte3;
}

new IntByte { IntVal = 10 } -> Byte0, Byte1, Byte2, Byte3.
class Program
{
    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        unsafe{
            byte[] byteArray = new byte[4];
            for(int i = 0; i != int.MaxValue; ++i)
            {
            fixed(byte* asByte = byteArray)
               *((int*)asByte) = 43;
               }
        }
        Console.WriteLine(sw.ElapsedMilliseconds);
        Console.Read();
    }
}

我的机器上平均约2770米

[StructLayout(LayoutKind.Explicit)]
struct Switcher
{
  [FieldOffset(0)]
  public int intVal;
  [FieldOffset(0)]
  public byte b0;
  [FieldOffset(1)]
  public byte b1;
  [FieldOffset(2)]
  public byte b2;
  [FieldOffset(3)]
  public byte b3;
}
class Program
{
    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        byte[] byteArray = new byte[4];
        Switcher swi = new Switcher();
        for(int i = 0; i != int.MaxValue; ++i)
        {
          swi.intVal = 43;
          byteArray[0] = swi.b0;
          byteArray[1] = swi.b1;
          byteArray[2] = swi.b2;
          byteArray[3] = swi.b3;
        }
        Console.WriteLine(sw.ElapsedMilliseconds);
        Console.Read();
    }
}

平均约4510米。

我认为,这可能是C#中最快的方式(通过按级阵列,先入为4x直下游/倾斜32)。

        private MemoryStream Convert(int[] Num, byte[] Bytes)
    {
        Buffer.BlockCopy(Num, 0, Bytes, 0, Bytes.Length);
        MemoryStream stream = new MemoryStream(Bytes);
        return stream;
    }

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.

我的膝上型计算机的时间安排为419毫米口径用于“联盟461毫秒用于“BiConvter<>/strong>。 然而,快速增长幅度更大。

这一方法用于公开源高性能算法HPCsharp图书馆,其中欧盟方法为Radix Sort提供微量提高。

工会较快,因为它没有双向掩饰,也没有临时的,而只是读出四轮 in中的正确 by。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace SplitIntIntoBytes
{
    [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();
            int sumTestUnion = testUnion();
            Timer.Stop();

            Console.WriteLine("time of Union:        " + Timer.ElapsedTicks + " milliseconds,  sum: " + sumTestUnion);

            Timer.Restart();
            int sumBitConverter = testBitConverter();
            Timer.Stop();

            Console.WriteLine("time of BitConverter: " + Timer.ElapsedTicks + " milliseconds,  sum: " + sumBitConverter);
            Console.ReadKey();
        }

        static int testBitConverter()
        {
            byte[] UnionBytes = new byte[4];
            byte[] SumOfBytes = new byte[4];
            SumOfBytes[0] = SumOfBytes[1] = SumOfBytes[2] = SumOfBytes[3] = 0;

            for (int i = 0; i < 10000; i++)
            {
                UnionBytes = BitConverter.GetBytes(i);
                SumOfBytes[0] += UnionBytes[0];
                SumOfBytes[1] += UnionBytes[1];
                SumOfBytes[2] += UnionBytes[2];
                SumOfBytes[3] += UnionBytes[3];
            }
            return SumOfBytes[0] + SumOfBytes[1] + SumOfBytes[2] + SumOfBytes[3];
        }

        static int testUnion()
        {
            byte[] UnionBytes;
            byte[] SumOfBytes = new byte[4];
            SumOfBytes[0] = SumOfBytes[1] = SumOfBytes[2] = SumOfBytes[3] = 0;

            FooUnion union = new FooUnion();

            for (int i = 0; i < 10000; i++)
            {
                union.integer = i;
                UnionBytes = new byte[] { union.byte0, union.byte1, union.byte2, union.byte3 };
                SumOfBytes[0] += UnionBytes[0];
                SumOfBytes[1] += UnionBytes[1];
                SumOfBytes[2] += UnionBytes[2];
                SumOfBytes[3] += UnionBytes[3];
            }
            return SumOfBytes[0] + SumOfBytes[1] + SumOfBytes[2] + SumOfBytes[3];
        }
    }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...