Looks like list.clear() will be slower,
Not always.
clear() has to clear out the references you used, however when you create a new object, it has to clear out the memory for the object before you can use it.
which in the second case, GC would deal with cleanup and make our life easy ?
The GC is not free. When you fill your CPU caches with garbage they won't work so well. You can speed up code significantly by reusing objects. It depends on your use case as to which is faster.
It is hard to find a decent micro-benchmark to demonstrate this, but in real programs, where the code is more complex, the impact is much higher than you might expect.
public class Main {
public static void main(String... args) {
for (int i = 0; i < 10; i++) {
long t1 = timeReuse();
long t2 = timeNewObject();
System.out.printf("Reuse time: %,d, New ArrayList time: %,d%n", t1, t2);
}
}
static final int RUNS = 50000;
static final byte[] a = new byte[8 * 1024];
static final byte[] b = new byte[a.length];
private static long timeReuse() {
long start = System.nanoTime();
List<Integer> ints = new ArrayList<Integer>();
for (int i = 0; i < RUNS; i++) {
ints.clear();
for (int j = -128; j < 128; j++)
ints.add(j);
System.arraycopy(a, 0, b, 0, a.length);
}
long time = System.nanoTime() - start;
return time / RUNS;
}
private static long timeNewObject() {
long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
List<Integer> ints = new ArrayList<Integer>(256);
for (int j = -128; j < 128; j++)
ints.add(j);
System.arraycopy(a, 0, b, 0, a.length);
}
long time = System.nanoTime() - start;
return time / RUNS;
}
}
prints
Reuse time: 1,964, New ArrayList time: 1,866
Reuse time: 1,889, New ArrayList time: 1,770
Reuse time: 1,163, New ArrayList time: 1,416
Reuse time: 1,250, New ArrayList time: 1,357
Reuse time: 1,253, New ArrayList time: 1,393
Reuse time: 1,106, New ArrayList time: 1,203
Reuse time: 1,103, New ArrayList time: 1,207
Reuse time: 1,113, New ArrayList time: 1,315
Reuse time: 1,104, New ArrayList time: 1,215
Reuse time: 1,106, New ArrayList time: 1,335
Note: the size of the buffer copied makes a difference.
The picture is far worse if you consider latency. This prints out the worst latency for each run.
public class Main {
public static void main(String... args) {
for (int i = 0; i < 10; i++) {
long t1 = timeReuse();
long t2 = timeNewObject();
System.out.printf("Reuse time: %,d, New ArrayList time: %,d%n", t1, t2);
}
}
static final int RUNS = 50000;
static final byte[] a = new byte[8 * 1024];
static final byte[] b = new byte[a.length];
private static long timeReuse() {
List<Integer> ints = new ArrayList<Integer>();
long longest = 0;
for (int i = 0; i < RUNS; i++) {
long start = System.nanoTime();
ints.clear();
for (int j = -128; j < 128; j++)
ints.add(j);
System.arraycopy(a, 0, b, 0, a.length);
long time = System.nanoTime() - start;
longest = Math.max(time, longest);
}
return longest;
}
private static long timeNewObject() {
long longest = 0;
for (int i = 0; i < RUNS; i++) {
long start = System.nanoTime();
List<Integer> ints = new ArrayList<Integer>(256);
for (int j = -128; j < 128; j++)
ints.add(j);
System.arraycopy(a, 0, b, 0, a.length);
long time = System.nanoTime() - start;
longest = Math.max(time, longest);
}
return longest;
}
}
prints when run with -Xmx32m
Reuse time: 74,879, New ArrayList time: 2,441,586
Reuse time: 26,889, New ArrayList time: 2,203,096
Reuse time: 25,920, New ArrayList time: 1,514,465
Reuse time: 13,013, New ArrayList time: 1,342,395
Reuse time: 12,368, New ArrayList time: 1,708,658
Reuse time: 12,272, New ArrayList time: 1,258,990
Reuse time: 12,559, New ArrayList time: 1,433,898
Reuse time: 12,144, New ArrayList time: 1,259,413
Reuse time: 12,433, New ArrayList time: 1,221,945
Reuse time: 12,352, New ArrayList time: 1,318,024