There are two obvious approaches: use Array.Copy and copy the elements one by one:
private static void ElementByElement<T>(T[] arg, int start) { for (int i = arg.Length - 1; i > start; i--) { arg[i] = arg[i - 1]; } } private static T BuiltInCopy<T>(T[] arg, int start) { Array.Copy(arg, start, arg, start + 1, arg.Length - start - 1); return arg[0]; }
For one thing, List<T> insert uses Array.Copy . Array.Copy , Array.Copy other hand, is nonequivalent and can do a lot of extra work: http://msdn.microsoft.com/en-us/library/z50k9bft.aspx
I expected Array.Copy be faster. However, the results of this MiniBench test surprised me.
internal class Program { private static int smallArraySize = 32; public static void Main(string[] args) { BenchArrayCopy(); } private static void BenchArrayCopy() { var smallArrayInt = new int[smallArraySize]; for (int i = 0; i < smallArraySize; i++) smallArrayInt[i] = i; var smallArrayString = new string[smallArraySize]; for (int i = 0; i < smallArraySize; i++) smallArrayString[i] = i.ToString(); var smallArrayDateTime = new DateTime[smallArraySize]; for (int i = 0; i < smallArraySize; i++) smallArrayDateTime[i] = DateTime.Now; var moveInt = new TestSuite<int[], int>("Move part of array right by 1: int") .Plus(BuiltInCopy, "Array.Copy()") .Plus(ElementByElement, "Element by element in a for loop") .RunTests(smallArrayInt, 0); var moveString = new TestSuite<string[], string>("Move part of array right by 1: string") .Plus(BuiltInCopy, "Array.Copy()") .Plus(ElementByElement, "Element by element in a for loop") .RunTests(smallArrayString, "0"); var moveDT = new TestSuite<DateTime[], DateTime>("Move part of array right by 1: DateTime") .Plus(BuiltInCopy, "Array.Copy()") .Plus(ElementByElement, "Element by element in a for loop") .RunTests(smallArrayDateTime, smallArrayDateTime[0]); moveInt.Display(ResultColumns.All, moveInt.FindBest()); moveString.Display(ResultColumns.All, moveInt.FindBest()); moveDT.Display(ResultColumns.All, moveInt.FindBest()); } private static T ElementByElement<T>(T[] arg) { int start = 8; for (int i = smallArraySize - 1; i > start; i--) { arg[i] = arg[i - 1]; } return arg[0]; } private static T BuiltInCopy<T>(T[] arg) { int start = 8; int length = smallArraySize - start - 1; Array.Copy(arg, start, arg, start + 1, length); return arg[0]; } }
The following are the results of two runs:
f:\MyProgramming\TimSort\Benchmarks\bin\Release>Benchmarks.exe ============ Move part of array right by 1: int ============ Array.Copy() 568475865 0:31.606 1,73 Element by element in a for loop 980013061 0:31.449 1,00 ============ Move part of array right by 1: string ============ Array.Copy() 478224336 0:31.618 2,06 Element by element in a for loop 220168237 0:30.926 4,38 ============ Move part of array right by 1: DateTime ============ Array.Copy() 382906030 0:27.870 2,27 Element by element in a for loop 458265102 0:29.239 1,99 f:\MyProgramming\TimSort\Benchmarks\bin\Release>Benchmarks.exe ============ Move part of array right by 1: int ============ Array.Copy() 500925013 0:28.514 1,76 Element by element in a for loop 988394220 0:31.967 1,00 ============ Move part of array right by 1: string ============ Array.Copy() 483178262 0:30.048 1,92 Element by element in a for loop 193092931 0:27.642 4,43 ============ Move part of array right by 1: DateTime ============ Array.Copy() 450569361 0:30.807 2,11 Element by element in a for loop 568054290 0:31.385 1,71
That is, for int and DateTime ElementByElement is much faster; and for string BuiltInCopy , it's twice as fast as ElementByElement (and twice as slow as ElementByElement for int ). I expect that the results for int and string will be very similar on a 32-bit machine, since the link to string on the stack is the same size as int , and no operations other than reading and writing to the memory of the stack should be involved.