5

Is there a more performant way to concatenate 2-d arrays than this?

  static void Main(string[] args)
    {

        int[][] array1 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } } ;             

        int[][] array2 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } };

        int[][] array3 = Concat(array1, array2);

    }

    private static int[][] Concat(int[][] array1, int[][] array2)
    {
        int array1Length = array1.Length;
        int array2Length = array2.Length;

        int[][] result = new int[array1Length + array2Length][];
        int i = 0;
        for (; i < array1Length; i++)
            result[i] = array1[i];

        for (; i < array2Length + array1Length; i++)
            result[i] = array2[i - array1Length];

        return result;    



    }

Edit: I would like to know if that's a good practice of deep concat of 2d array

        private static int[][] DeepConcat(int[][] array1, int[][] array2)
    {
        int array1Length = array1.Length;
        int array2Length = array2.Length;

        int[][] result = new int[array1Length + array2Length][];
        int i = 0;
        for (; i < array1Length; i++)
        {
            result[i] = new int[array1[i].Length];
            for (int j = 0; j < array1[i].Length; j++)
            {
                result[i][j] = array1[i][j];
            }
        }
        for (; i < array2Length + array1Length; i++)
        {
            result[i] = new int[array2[i - array1Length].Length];
            for (int j = 0; j < array2[i - array1Length].Length; j++)
            {
                result[i][j] = array2[i - array1Length][j];
            }

        }
        return result;

    }
mustafabar
  • 2,317
  • 6
  • 31
  • 47
  • 2
    Have you identified this as something that's taking a significant amount of your processing time? If not then leave it alone until it does. – ChrisF Jul 07 '10 at 13:57
  • How performant is the existing method? – Restore the Data Dumps Jul 07 '10 at 14:02
  • the thing is I am going to incorporate this to a very critical code and according to my test results, it is performing fine within acceptable range, I just wanna make sure it is the best I can do – mustafabar Jul 07 '10 at 14:09

3 Answers3

3

You could use a linked list of int[] instead so you don't need to re-allocate any new memory.

See LinkedList<T>, or if it doesn't perform exactly as you want for concat you can make your own easily.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
3

Your issue can be simplified to the same question as this one.

So my solution for you would be:

    private static int[][] Concat(int[][] array1, int[][] array2)
    {
        int[][] result = new int[array1.Length + array2.Length][];

        array1.CopyTo(result, 0);
        array2.CopyTo(result, array1.Length);

        return result;
    }

**I can't find the comment link below the original question. So editing my own post.*

Mustafa, I would like to ask you: Do you intend to copy arrays in new memory? Because your original concat method only copy array references. So after creating array3 (using original concat()), if you change anything in array1 and array2, then array3 will change as well. I hope you are aware of that. If you intended to have separate memory block for array3, then only use my method (or deltreme's method).

MoonKnight
  • 23,214
  • 40
  • 145
  • 277
bits
  • 8,110
  • 8
  • 46
  • 55
  • no .. the copyto also copies references .. check this out int[][] array1 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } } ; int[][] array3 = new int[array1.Length][]; array1.CopyTo(array3,0); array1[0][0] = 1000; if (array1[0][0] == array3[0][0]) Console.WriteLine("Gotcha"); – mustafabar Jul 08 '10 at 06:35
  • Oh wow. Thanks Mustafa, for letting me know about this. I learned something as well. Atleast in that case, this solution perfectly suits your requirement. Because you didn't care about copying references. – bits Jul 08 '10 at 06:47
0

I doubt this will be alot faster, but perhaps it's a bit more readable:

int[][] array3 = new int[array1.Length + array2.Length][];

Array.Copy(array1, 0, array3, 0, array1.Length);
Array.Copy(array2, 0, array3, array1.Length, array2.Length);

Edit: in a critical part of your application, it might be worth it - it's a shame Buffer.BlockCopy doesn't work on "nested" int[] arrays :(

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72