How to get auxiliary array without cloning

I know that in C # we can always get the submatrix of a given array using the method Array.Copy(). However, this will consume more memory and processing time, which is not necessary in a read-only situation. For example, I write a program with a heavy load, which very often exchanges messages with other nodes in the cluster. The first 20 bytes of each message are the message header, and the remaining bytes make up the message body. Therefore, I will divide the received raw message into an array of header bytes and an array of body bytes in order to process them separately. However, this will obviously consume dual memory and extra time. In C, we can easily use a pointer and assign an offset to it to access different parts of the array. For example, in C, if we havechar a[] = "ABCDEFGHIJKLMN", we can declare char* ptr = a + 3to represent an array DEFGHIJKLMN.

Is there a way to accomplish this in C #?

+4
source share
3 answers

You may be interested in ArraySegmentseither unsafe.


ArraySegments limits the section of a one-dimensional array.

Check array actions in action

An example of using ArraySegments:

 int[] array = { 10, 20, 30 };

 ArraySegment<int> segment = new ArraySegment<int>(array, 1, 2);
 // The segment contains offset = 1, count = 2 and range = { 20, 30 }

unsafe define an unsafe context in which pointers can be used.

Insecure usage example:

    int[] a = { 4, 5, 6, 7, 8 };

    unsafe
    {
        fixed (int* c = a)
        {
            // use the pointer
        }
    }
+5
source

First of all, you should consider this a premature optimization.

But you can use several ways to reduce memory consumption if you are sure that you really need it:

1) Flyweight https://en.wikipedia.org/wiki/Flyweight_pattern .

2) .

3) C #.

, flyweight pattern .

+1

, #? , , 20 .

You can easily accomplish this using the gaps and recommendations suggested by Jonathan Reinhart above if you have the entire initial array in the memory array, but it looks like you can have it in a network stream, which means the property may be a bit more involved in reading the initial 20 bytes from the stream.

Something along the lines of:

class Message
{
    private readonly Stream _stream;
    private byte[] _inMemoryBytes;

    public Message(Stream stream)
    {
        _stream = stream;
    }

    public IEnumerable<byte> Header
    {
        get
        {
            if (_inMemoryBytes.Length >= 20)
                return _inMemoryBytes.Take(20);

            _stream.Read(_inMemoryBytes, 0, 20);
            return _inMemoryBytes.Take(20);
        }
    }

    public IEnumerable<byte> FullMessage
    {
        get
        {
            // Read and return the whole message. You might want amend to data already read.
        }
    }
}
0
source

Source: https://habr.com/ru/post/1598317/


All Articles