Home > Software design >  Fast copy from array to structure array in c#
Fast copy from array to structure array in c#

Time:08-11

Is there any way to fast-copy an array to a member of another structure array without using a for loop? I want to print out "6" when I run this code.

using System;
                    
public class Program
{
    struct output
    {
        public int A;
        public int B;
    }
    public static void Main()
    {
        var output_array = new output[10];
        var a_array = new int[] { 0, 2, 4, 6 ,8, 10, 12, 14, 16, 18};
        var b_array = new int[] { 1, 3, 5, 7 ,9, 11, 13, 15, 17, 19};
        // Copy a_array to output[].A 
        // and copy b_array_to output[].B , without using any loop.
        Console.WriteLine(output_array[3].A);
    }
}

CodePudding user response:

It's not going to be specifically fast but it is succinct to use the Zip extension method:

var a_array = new int[] { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 };
var b_array = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };

var output_array = a_array.Zip(b_array, (a, b) => new output { A = a, B = b }).ToArray();

This obviously creates the array, rather than populating an existing array. That shouldn't be an issue for situations like your example, but maybe it is in some real-world situations. In that case, you could create an array and then Array.Copy the elements over.

EDIT:

Actually, I wonder whether I might have misinterpreted your requirement, in which case creating a new array might be an issue. You have included b_array in your code but a more careful reading of your question and your code seems to suggest that that is irrelevant. Please take care to include ONLY what is relevant to the issue because anything else can cloud the issue and waste everyone's time.

If you specifically want the contents of a_array copied into an existing array and b_array is irrelevant then you can't really do it without a loop but, again, LINQ can help flatten that loop:

var output_array = new output[10];
var a_array = new int[] { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 };

Array.ForEach(Enumerable.Range(0, Math.Min(output_array.Length, a_array.Length)).ToArray(),
              i => output_array[i].A = a_array[i]);

I've included that Math.Min call to allow for the two arrays to be different lengths but, if you know they're not, you can do away with that and just use one array. Obviously that ForEach call is masking a loop but the actual you see is more succinct. For a one-line loop though, is it really worth the effort and the fact that you have to generate a int array to do it?

I should also point that, while this looks like it would be a problem with value types:

output_array[i].A = a_array[i]

it actually doesn't. Indexing arrays actually provides direct access to the element, rather than creating a copy, so setting a property of that element is not a problem, even for value types.

CodePudding user response:

Thanks, John for the answer. As you recommended I modified my code. Performance is very important. Not like the simple example above, I have to deal with millions of values in the array. It's the reason why I want to avoid using any loop solutions. I don't know very well how arrays handle memory, but I expected a solution that deals with memory or something that is working more in lower level.

CodePudding user response:

The memory layout of a_array and output_array will be different so you can't use any tricks with memory copying the bytes.

There are ways to achieve the copy without using an assign in a for loop, e,g.

for (var i = 0; i < 10; i  )
{
    output_array[i].A = a_array[i];
    // output_array[i].B = b_array[i];
}

but I doubt anything is going to be faster than that. Of course, I haven't tested and benchmarked it.


Perhaps a better solution is not to copy the bytes at all.

  • Related