0

I programming in C#.

I am looking for efficient way to set double (or any primitive) value into exist byte array in specific offset. I am familiar with BitConverter.GetBytes and the Buffer.BlockCopy command. I am looking for function that enable my to set the primitive value directly to specific byte offset in the array, without new memory allocation Something like this code

public unsafe static void  SetBytes(int value,byte[] output,int index)
    {
        fixed(byte* b = output)
            *((int*)b+index) = value;

    }

The regular version:

 public unsafe static void SetBytesArray(int value, byte[] output, int index)
        {
            byte[] byteValue = BitConverter.GetBytes(value);
            Buffer.BlockCopy(byteValue, 0, output, index * 4, 4);
        }

The friends in the forum ask me to add measure compression between the extreme version above , and to regular version

I create array of 1000 bytes, In each cycle I fill all the array with constant int value. I repeat on the above action for 10000 times , I measure the time with StopWatch.

Avg time for one cycle:

  1. extreme - 0.004 ticks (SetBytes)

  2. regular - 0.028 ticks (SetBytesArray)

Thanks,

Mak

6
  • So you have some buffer output and at position index you want to overwrite the next 4 bytes with the value value? Are you sure you need unsafe and fixed for this? Why not break value into 4 byte values and overwrite those indexes of output? Commented Apr 18, 2018 at 15:21
  • Because to do that is not efficient Enough , GetBytes of any other option allocate new memory in every step, I am working in real time ,in high speed with high volume data. Commented Apr 18, 2018 at 15:21
  • You just need to do unchecked{ output[index] = byte1, output[index+1]=byte2 .... } - that will be most efficient way Commented Apr 18, 2018 at 15:33
  • It would be interesting to have two versions of this. One that uses Array Copy and Array SetByte and one that uses your extreme version. You could measure the difference in your specific scenario from a repeatable test. Commented Apr 18, 2018 at 15:40
  • 1
    Not sure what the hangup might be, but the posted snippet does have a bug. The index variable does not act as a byte index, it indexes ints. Use byte* b = &output[index] instead. Commented Apr 18, 2018 at 16:13

1 Answer 1

1

As far as I can see, what you have should work (once you've fixed up the compile error).

For example:

using System;
using System.Linq;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            byte[] data = new byte[16];
            int value = 0x12345678;
            SetBytes(value, data, 5);

            // This prints "0, 0, 0, 0, 0, 78, 56, 34, 12, 0, 0, 0, 0, 0, 0, 0"
            Console.WriteLine(string.Join(", ", data.Select(b => b.ToString("x"))));
        }

        public static unsafe void SetBytes(int value, byte[] output, int index)
        {
            fixed (byte* b = output)
                *((int*)(b + index)) = value;
        }
    }
}

[EDIT: Changed to work with byte offset rather than int offset]

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, I notice that only now :-) .But I am looking for index offset in byte not in int, you have any suggestion ?
@MAK Sorry, went home for the day! To make it use a byte index you just need to change it to *((int*)(b + index)) = value;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.