LANG-839 Add tests to compare extractIndices+removeAll with direct use of BitSet in new version of removeAll

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1395943 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2012-10-09 10:28:08 +00:00
parent 17910d3cc7
commit 43a2736e22
2 changed files with 93 additions and 1 deletions

View File

@ -5739,7 +5739,8 @@ public static boolean[] removeElements(boolean[] array, boolean... values) {
* @return new array of same type minus elements specified by unique values of {@code indices}
* @since 3.0.1
*/
private static Object removeAll(Object array, int... indices) {
// package protected for access by unit tests
static Object removeAll(Object array, int... indices) {
int length = getLength(array);
int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed

View File

@ -16,6 +16,7 @@
*/
package org.apache.commons.lang3;
import java.lang.reflect.Array;
import java.util.BitSet;
import java.util.HashSet;
@ -28,6 +29,7 @@
public class HashSetvBitSetTest {
private static final int LOOPS = 2000; // number of times to invoke methods
private static final int LOOPS2 = 10000;
@Test
public void testTimes() {
@ -42,6 +44,7 @@ public void testTimes() {
printTimes(1000);
printTimes(2000);
}
private void printTimes(int count) {
long hashSet = timeHashSet(count);
long bitSet = timeBitSet(count);
@ -109,4 +112,92 @@ private static int[] extractIndices(BitSet coll) {
}
return result;
}
@Test
public void testTimesExtractOrBitset() {
final BitSet toRemove = new BitSet();
final int[] array = new int[100];
toRemove.set(10, 20);
timeBitSetRemoveAll(array, toRemove); // warmup
timeExtractRemoveAll(array, toRemove); // warmup
printTimes(100,1);
printTimes(100,10);
printTimes(100,50);
printTimes(100,100);
printTimes(1000,10);
printTimes(1000,100);
printTimes(1000,500);
printTimes(1000,1000);
}
private void printTimes(int arraySize, int bitSetSize) {
int[] array = new int[arraySize];
BitSet remove = new BitSet();
for (int i = 0; i < bitSetSize; i++) {
remove.set(i);
}
long bitSet = timeBitSetRemoveAll(array, remove );
long extract = timeExtractRemoveAll(array, remove);
// If percent is less than 100, then direct use of bitset is faster
System.out.println("Ratio="+(bitSet*100/extract)+"% array="+array.length+" count="+remove.cardinality()+" extract="+extract+" bitset="+bitSet);
}
private long timeBitSetRemoveAll(int[] array, BitSet toRemove) {
int[] output = new int[0];
long start = System.nanoTime();
for(int i = 0; i < LOOPS2; i++){
output = (int[]) removeAll(array, toRemove);
}
long end = System.nanoTime();
Assert.assertEquals(array.length-toRemove.cardinality(), output.length);
return end - start;
}
private long timeExtractRemoveAll(int[] array, BitSet toRemove) {
int[] output = new int[0];
long start = System.nanoTime();
for(int i = 0; i < LOOPS2; i++){
final int[] extractIndices = extractIndices(toRemove);
output = (int[]) ArrayUtils.removeAll((Object)array, extractIndices);
}
long end = System.nanoTime();
Assert.assertEquals(array.length-toRemove.cardinality(), output.length);
return end - start;
}
/**
* Removes multiple array elements specified by indices.
*
* @param array source
* @param indices to remove
* @return new array of same type minus elements specified by the set bits in {@code indices}
* @since 3.2
*/
// package protected for access by unit tests
static Object removeAll(Object array, BitSet indices) {
final int srcLength = ArrayUtils.getLength(array);
final int maxIndex = indices.length();
if (maxIndex > srcLength) { // TODO necessary? Can check this when creating the BitSit
throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
}
final int removals = indices.cardinality(); // true bits are items to remove
Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
int srcIndex=0;
int destIndex=0;
int count;
int set;
while((set = indices.nextSetBit(srcIndex)) != -1){
count = set - srcIndex;
if (count > 0) {
System.arraycopy(array, srcIndex, result, destIndex, count);
destIndex += count;
}
srcIndex = indices.nextClearBit(set);
}
count = srcLength - srcIndex;
if (count > 0) {
System.arraycopy(array, srcIndex, result, destIndex, count);
}
return result;
}
}