We found in LZDecoder that using System.arrayCopy with doubling size
is faster than Arrays.fill (especially for larger arrays).
We can apply that knowledge in the BasicArrayCache, where there are
some use cases which require clearing out the array prior to returning
it.


diff --git a/src/org/tukaani/xz/BasicArrayCache.java
b/src/org/tukaani/xz/BasicArrayCache.java
index 90ebe1f..0148fbe 100644
--- a/src/org/tukaani/xz/BasicArrayCache.java
+++ b/src/org/tukaani/xz/BasicArrayCache.java
@@ -11,7 +11,6 @@ package org.tukaani.xz;

 import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
-import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.Map;

@@ -239,8 +238,13 @@ public class BasicArrayCache extends ArrayCache {

         if (array == null)
             array = new byte[size];
-        else if (fillWithZeros)
-            Arrays.fill(array, (byte)0x00);
+        else if (fillWithZeros) {
+            array[0] = (byte)0x00;
+            array[1] = (byte)0x00;
+            array[2] = (byte)0x00;
+            array[3] = (byte)0x00;
+            fillArrayFromFirstFourValues(array, array.length);
+        }

         return array;
     }
@@ -263,8 +267,13 @@ public class BasicArrayCache extends ArrayCache {

         if (array == null)
             array = new int[size];
-        else if (fillWithZeros)
-            Arrays.fill(array, 0);
+        else if (fillWithZeros) {
+            array[0] = 0;
+            array[1] = 0;
+            array[2] = 0;
+            array[3] = 0;
+            fillArrayFromFirstFourValues(array, array.length);
+        }

         return array;
     }
@@ -278,4 +287,21 @@ public class BasicArrayCache extends ArrayCache {
     public void putArray(int[] array) {
         putArray(intArrayCache, array, array.length);
     }
+
+    /**
+     * Repeats the first 4 values in the array to fill the contents.
+     */
+    private static void fillArrayFromFirstFourValues(Object array,
int length) {
+        int toCopy = 4;
+        int remaining = length - toCopy;
+        do {
+            System.arraycopy(array, 0, array, toCopy, toCopy);
+            remaining -= toCopy;
+            toCopy <<= 1;
+        } while (remaining >= toCopy);
+
+        if (remaining != 0) {
+            System.arraycopy(array, 0, array, toCopy, remaining);
+        }
+    }
 }

Reply via email to