An extremely fast way to clone a gear array values โ€‹โ€‹into a second array?

I am currently working on an application that is responsible for calculating random permutations of a gear array.

Currently, most of the time in the application is spent copying the array at each iteration (total 1 million iterations). On my current system, the whole process takes 50 seconds, and 39 of those seconds spent cloning the array.

My array cloning procedure is as follows:

public static int[][] CopyArray(this int[][] source) { int[][] destination = new int[source.Length][]; // For each Row for (int y = 0; y < source.Length; y++) { // Initialize Array destination[y] = new int[source[y].Length]; // For each Column for (int x = 0; x < destination[y].Length; x++) { destination[y][x] = source[y][x]; } } return destination; } 

Is there a way, safe or unsafe, to achieve the same effect as above, much faster?

+7
source share
5 answers

Any of these should work for you. They both work about the same amount of time and are much faster than your method.

 // 100 passes on a int[1000][1000] set size // 701% faster than original (14.26%) static int[][] CopyArrayLinq(int[][] source) { return source.Select(s => s.ToArray()).ToArray(); } // 752% faster than original (13.38%) static int[][] CopyArrayBuiltIn(int[][] source) { var len = source.Length; var dest = new int[len][]; for (var x = 0; x < len; x++) { var inner = source[x]; var ilen = inner.Length; var newer = new int[ilen]; Array.Copy(inner, newer, ilen); dest[x] = newer; } return dest; } 
+17
source

Have you looked at the C # Array.Clone method ?

Edit: Actually, I believe Array.Copy could be more efficient / faster for your needs.

I did a quick test, and it seems that all changes in the destination do not affect the source:

 int[] source = new int[3]{1,2,3}; int[] destination = new int[source.Length]; Array.Copy(source, destination, source.Length); destination[0]++; // or destination[0] = destination[0] + 1; 

leads to:

  source = { 1 , 2 , 3 } destination = { 2, 2, 3 } 

Is this the result you were looking for?

 public static int[][] CopyArray(int[][] source) { int[][] destination = new int[source.Length][]; Array.Copy(source, destination, source.Length); return destination; } 

basically fulfills what you seek, I believe.

0
source

how about serializing / deserializing the array, if you use memory streams and binary serialization, I think it should be pretty fast.

0
source

You can use Array.Clone for the inner loop:

 public static int[][] CopyArray(this int[][] source) { int[][] destination = new int[source.Length][]; // For each Row for(int y = 0;y < source.Length;y++) { destination[y] = (int[])source[y].Clone(); } return destination; } 

Another alternative for the inner loop is Buffer.BlockCopy , but I did not rate its performance against Array.Clone - maybe this is faster:

 destination[y] = new int[source[y].Length]; Buffer.BlockCopy(source[y], 0, destination[y], 0, source[y].Length * 4); 

Edit: Buffer.BlockCopy accepts a number for bytes to copy the count parameter, not the number of elements in the array.

0
source

A faster way to copy objects is to not copy them at all - have you considered this option? If you just need to create permutations, you do not need to copy data on each of them - just change the array. This approach will not work if you need to continue the results of previous calls. In any case, review your code to see if you are copying more data than the time you need.

0
source

All Articles