In a previous question Why clone() is the best way for copying arrays? @procrastinator demonstrates that given an array, original.clone() is in average two times faster than System.arraycopy(original, 0, destination, 0, length)
However I have noticed that when using the clone method it is not possible to modify the length of the destination array, nor copy only a portion of the array. Using System.arraycopy I would do:
New array with extra positions
int[] original = new int[] {1,2,3,4,5};
int originalSize = original.length;
int newSize = originalSize + 1;
int[] destination = new int[newSize];
System.arraycopy(original, 0, destination, 0)
destination[newSize - 1] = newValue;
New array with less positions
int[] original = new int[] {1,2,3,4,5};
int originalSize = original.length;
int newSize = originalSize - 1;
int[] destination = new int[newSize];
System.arraycopy(original, 1, destination, 0)
(Notice that the arrays in the example are small for the sake of clarity but in the real case they are bigger)
Is there a way to achieve a similar performance to clone in any of the scenarios? Or in these cases we must use the System.arraycopy method?
EDIT1 :
As suggested by @aUserHimself I have tried (without any success) to measure the performance of the System.arraycopy against the Stream interface. Below I provide the Benchmark code and its results:
@Benchmark
public int[] SystemArraycopySmaller() {
    final int length = this.size;
    int[] destination = new int[length / 2];
    System.arraycopy(this.original, 0, destination, 0, length / 2);
    return destination;
}
@Benchmark
public int[] StreamArraycopySmaller() {
    final int length = this.size;
    int[] destination = Arrays.stream(this.original).filter(i -> i < length / 2).toArray();
    return destination;
}
@Benchmark
public int[] SystemArraycopyBigger() {
    final int length = this.size;
    int[] destination = new int[length * length];
    for (int i = 0; i < length; i++) {
        System.arraycopy(this.original, 0, destination, i * length, length);
    }
    return destination;
}
@Benchmark
public int[] StreamArraycopyBigger() {
    int[] destination = Arrays.stream(this.original).flatMap(i -> Arrays.stream(this.original).map(j -> j)).toArray();
    return destination;
}
Results:
Benchmark                               (size)   Mode  Cnt      Score      Error  Units
SampleBenchmark.StreamArraycopyBigger    10000  thrpt   10        ≈ 0             ops/s
SampleBenchmark.StreamArraycopyBigger     1000  thrpt   10        ≈ 0             ops/s
SampleBenchmark.StreamArraycopyBigger      100  thrpt   10     11,997 ±    0,002  ops/s
SampleBenchmark.StreamArraycopyBigger       10  thrpt   10    608,899 ±    8,975  ops/s
SampleBenchmark.StreamArraycopyBigger        1  thrpt   10   6373,457 ±  313,626  ops/s
SampleBenchmark.StreamArraycopySmaller   10000  thrpt   10     36,692 ±    0,728  ops/s
SampleBenchmark.StreamArraycopySmaller    1000  thrpt   10    328,875 ±    2,259  ops/s
SampleBenchmark.StreamArraycopySmaller     100  thrpt   10   2141,368 ±    8,832  ops/s
SampleBenchmark.StreamArraycopySmaller      10  thrpt   10   9018,659 ±  118,933  ops/s
SampleBenchmark.StreamArraycopySmaller       1  thrpt   10  12954,709 ±  114,621  ops/s
SampleBenchmark.SystemArraycopyBigger    10000  thrpt   10        ≈ 0             ops/s
SampleBenchmark.SystemArraycopyBigger     1000  thrpt   10        ≈ 0             ops/s
SampleBenchmark.SystemArraycopyBigger      100  thrpt   10    161,004 ±    1,361  ops/s
SampleBenchmark.SystemArraycopyBigger       10  thrpt   10  10039,397 ±  123,553  ops/s
SampleBenchmark.SystemArraycopyBigger        1  thrpt   10  42539,869 ± 1965,589  ops/s
SampleBenchmark.SystemArraycopySmaller   10000  thrpt   10    399,816 ±    6,503  ops/s
SampleBenchmark.SystemArraycopySmaller    1000  thrpt   10   3189,271 ±  117,936  ops/s
SampleBenchmark.SystemArraycopySmaller     100  thrpt   10  22533,102 ±  183,870  ops/s
SampleBenchmark.SystemArraycopySmaller      10  thrpt   10  45577,443 ± 1656,788  ops/s
SampleBenchmark.SystemArraycopySmaller       1  thrpt   10  41657,519 ±  183,266  ops/s
Does anyone know about any other possible approach?
EDIT2 :
I have updated the benchmark codes and results with the suggested modifications to make the comparison even. However, for the bigger experimentation there is some error (probably due to the heap size I suppose) and for the smaller experimentation the Arraycopy still outperforms the Stream one. So I suppose there is no better way to copy arrays when the destination differs on size than using arraycopy.
 
    