package cmu.defect4j.lang3;
import java.lang.reflect.InvocationTargetException;
import java.util.BitSet;
import java.util.HashSet;
import gov.nasa.jpf.util.test.TestJPF;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
public class HashSetvBitSetTest extends TestJPF {
private final String[] config = {
"+search.class= .search.RandomSearch",
"+nhandler.delegateUnhandledNative",
"+classpath+=${jpf-core}/lib/junit-4.11.jar,${jpf-core}/lib/commons-lang3-3.2-SNAPSHOT.jar,${jpf-core}/lib/easymock.jar,${jpf-core}/lib/commons-io.jar" };
public static void main(String[] testMethods) {
runTestsOfThisClass(testMethods);
}
@Ignore // works but long running (2376s)
@Test // (timeout=120000)
public void testTimesExtractOrBitset() throws Exception {
if (verifyNoPropertyViolation(config)) {
org.apache.commons.lang3.HashSetvBitSetTest object = new org.apache.commons.lang3.HashSetvBitSetTest();
object.testTimesExtractOrBitset();
}
}
@Test
// (timeout=120000)
public void testTimes() throws Exception {
if (verifyNoPropertyViolation(config)) {
fail();// TODO remove, long-running & failing test
timeHashSet(10); // warmup
timeBitSet(10); // warmup
long timeDiff = printTimes(0);
timeDiff += printTimes(5);
timeDiff += printTimes(10);
timeDiff += printTimes(200);
timeDiff += printTimes(50);
timeDiff += printTimes(100);
timeDiff += printTimes(1000);
timeDiff += printTimes(2000);
Assert.assertTrue(timeDiff <= 0);
// org.apache.commons.lang3.HashSetvBitSetTest object = new
// org.apache.commons.lang3.HashSetvBitSetTest();
// object.testTimes();
}
}
/**
* @return bitSet - HashSet
*/
private long printTimes(final int count) {
final long hashSet = timeHashSet(count);
final long bitSet = timeBitSet(count);
// If percent is less than 100, then bitset is faster
System.out.println("Ratio=" + (bitSet * 100 / hashSet) + "% count="
+ count + " hash=" + hashSet + " bits=" + bitSet);
return bitSet - hashSet;
}
@SuppressWarnings("boxing")
private static int[] testHashSet(final int count) {
final HashSet<Integer> toRemove = new HashSet<Integer>();
int found = 0;
for (int i = 0; i < count; i++) {
toRemove.add(found++);
}
return extractIndices(toRemove);
}
private static long timeHashSet(final int count) {
int[] result = new int[0];
final long start = System.nanoTime();
for (int i = 0; i < LOOPS; i++) {
result = testHashSet(count);
}
final long elapsed = System.nanoTime() - start;
Assert.assertEquals(count, result.length);
return elapsed;
}
private static long timeBitSet(final int count) {
int[] result = new int[0];
final long start = System.nanoTime();
for (int i = 0; i < LOOPS; i++) {
result = testBitSet(count);
}
final long elapsed = System.nanoTime() - start;
Assert.assertEquals(count, result.length);
return elapsed;
}
private static int[] testBitSet(final int count) {
final BitSet toRemove = new BitSet();
int found = 0;
for (int i = 0; i < count; i++) {
toRemove.set(found++);
}
return extractIndices(toRemove);
}
private static int[] extractIndices(final HashSet<Integer> coll) {
final int[] result = new int[coll.size()];
int i = 0;
for (final Integer index : coll) {
result[i++] = index.intValue();
}
return result;
}
private static int[] extractIndices(final BitSet coll) {
final int[] result = new int[coll.cardinality()];
int i = 0;
int j = 0;
while ((j = coll.nextSetBit(j)) != -1) {
result[i++] = j++;
}
return result;
}
private static final int LOOPS = 2000; // number of times to invoke methods
private static final int LOOPS2 = 10000;
@SuppressWarnings("unused")
private long printTimes(final int arraySize, final int bitSetSize) {
final int[] array = new int[arraySize];
final BitSet remove = new BitSet();
for (int i = 0; i < bitSetSize; i++) {
remove.set(i);
}
final long bitSet = timeBitSetRemoveAll(array, remove);
final 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);
return bitSet - extract;
}
private long timeBitSetRemoveAll(final int[] array, final BitSet toRemove) {
int[] output = new int[0];
final long start = System.nanoTime();
for (int i = 0; i < LOOPS2; i++) {
try {
output = (int[]) ArrayUtils.class.getMethod("removeAll",
Object.class, int[].class).invoke(null, (Object) array,
toRemove);
} catch (IllegalAccessException | NoSuchMethodException
| SecurityException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
final long end = System.nanoTime();
Assert.assertEquals(array.length - toRemove.cardinality(),
output.length);
return end - start;
}
private long timeExtractRemoveAll(final int[] array, final BitSet toRemove) {
int[] output = new int[0];
final long start = System.nanoTime();
for (int i = 0; i < LOOPS2; i++) {
final int[] extractIndices = extractIndices(toRemove);
try {
output = (int[]) ArrayUtils.class.getMethod("removeAll",
Object.class, int[].class).invoke(null, (Object) array,
extractIndices);
} catch (IllegalAccessException | NoSuchMethodException
| SecurityException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
final long end = System.nanoTime();
Assert.assertEquals(array.length - toRemove.cardinality(),
output.length);
return end - start;
}
}