I want to allocate a new array with the length N and fill it up by repeating a given array. The interface looks like this:
<T> T[] repeat(T[] array, int n);
To clarify what I mean here is a small example:
String a = {"a", "b", "c"};
// b = {"a", "b", "c", "a", "b", "c", "a", "b", "c", "a"}
String b = repeat(a, 10);
Most of the programmer will come up with the following solution (for simplicity of array generation a specific type was chosen):
public String[] repeat(String[] array, int n) {
String[] repeated = new String[n];
for (int i = 0; i < n; i++) {
repeated[i] = array[i % array.length];
}
return repeated;
}
Is there a faster way to do this?
I came up with this generic solution:
Theory
System.arraycopy
is a native call. Therefore it is very fast but it doesn't mean it is the fastest way.Every other solution copys the array element by element. My solution copys larger blocks. Every iteration duplicates the existing elements in the array which means the loop will run at most log2(n) times.
Profiling reports
Input
Here is my benchmark code to reproduce the results:
Results
As you can see the native call method is the fastest way to repeat an array.
Additional Results
Further I was asked to benchmark these methods with various inputs.
Input ranges
That means there are
SIZE x NEW_LENGTH
tests and here are the results:As expected the native call is always ahead (about 2 times faster than the loop version).
You don't need to
Min
on each loop, you can extract that to afterwards. You also double the offset twice in each loop.However, mine doesn't appear to measurably faster, sometimes faster, sometimes not, but it's an alternative to the Min call.
Code:
The other thing I tried was calculating the number of times I could safely double and while it was some what a dead end performance wise I thought it interesting to show: