LANG-1110: Implement HashSetvBitSetTest using JMH (side effect: closes #253, closes #191)
Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/e685d847 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/e685d847 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/e685d847 Branch: refs/heads/release Commit: e685d847b4c70e354e47ea3990cefda3265aa5c6 Parents: 111fd3f Author: pascalschumacher <pascalschumac...@gmx.net> Authored: Fri Apr 28 17:36:58 2017 +0200 Committer: pascalschumacher <pascalschumac...@gmx.net> Committed: Fri Apr 28 17:36:58 2017 +0200 ---------------------------------------------------------------------- src/changes/changes.xml | 2 + .../commons/lang3/HashSetvBitSetTest.java | 156 +++++-------------- 2 files changed, 41 insertions(+), 117 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/e685d847/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f4df009..a679df8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -46,6 +46,8 @@ The <action> type attribute can be add,update,fix,remove. <body> <release version="3.6" date="2017-MM-DD" description="TBD"> + <action issue="LANG-1110" type="update" dev="pschumacher" due-to="Bruno P. Kinoshita">Implement HashSetvBitSetTest using JMH</action> + <action issue="LANG-1256" type="add" dev="pschumacher" due-to="C0rWin">Add JMH maven dependencies</action> <action issue="LANG-1167" type="add" dev="chtompki" due-to="Mark Dacek">Add null filter to ReflectionToStringBuilder</action> <action issue="LANG-1312" type="fix" dev="britter">LocaleUtils#toLocale does not support language followed by UN M.49 numeric-3 area code followed by variant</action> <action issue="LANG-1300" type="fix" dev="chtompki" due-to="Mark Dacek">Clarify or improve behaviour of int-based indexOf methods in StringUtils</action> http://git-wip-us.apache.org/repos/asf/commons-lang/blob/e685d847/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java b/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java index 994631f..cafb298 100644 --- a/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java +++ b/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java @@ -18,86 +18,63 @@ package org.apache.commons.lang3; import java.util.BitSet; import java.util.HashSet; +import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; /** * Test to show whether using BitSet for removeAll() methods is faster than using HashSet. */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) public class HashSetvBitSetTest { - private static final int LOOPS = 2000; // number of times to invoke methods - private static final int LOOPS2 = 10000; + private static final int numberOfElementsToCompute = 10; - @Test - public void testTimes() { - 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); - } - - /** - * @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; - } - - 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); + @Benchmark + public int[] testHashSet() { + final HashSet<Integer> toRemove = new HashSet<Integer>(); + int found = 0; + for (int i = 0; i < numberOfElementsToCompute; i++) { + toRemove.add(found++); } - final long elapsed = System.nanoTime() - start; - Assert.assertEquals(count, result.length); - return elapsed; + return extractIndices(toRemove); } - @SuppressWarnings("boxing") - private static int[] testHashSet(final int count) { - final HashSet<Integer> toRemove = new HashSet<>(); - int found = 0; - for (int i = 0; i < count; i++) { - toRemove.add(found++); - } - return extractIndices(toRemove); - } - - private static int[] testBitSet(final int count) { + @Benchmark + public int[] testBitSet() { final BitSet toRemove = new BitSet(); int found = 0; - for (int i = 0; i < count; i++) { + for (int i = 0; i < numberOfElementsToCompute; i++) { toRemove.set(found++); } return extractIndices(toRemove); } + + @Benchmark + public int[] timeBitSetRemoveAll() { + final BitSet toRemove = new BitSet(); + final int[] array = new int[100]; + toRemove.set(10, 20); + return (int[]) ArrayUtils.removeAll(array, toRemove); + } + @Benchmark + public int[] timeExtractRemoveAll() { + final BitSet toRemove = new BitSet(); + final int[] array = new int[100]; + toRemove.set(10, 20); + final int[] extractIndices = extractIndices(toRemove); + return (int[]) ArrayUtils.removeAll((Object)array, extractIndices); + } + // --- utility methods private static int[] extractIndices(final HashSet<Integer> coll) { final int[] result = new int[coll.size()]; int i = 0; @@ -116,59 +93,4 @@ public class HashSetvBitSetTest { } 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 - long timeDiff = printTimes(100,1); - timeDiff += printTimes(100,10); - timeDiff += printTimes(100,50); - timeDiff += printTimes(100,100); - timeDiff += printTimes(1000,10); - timeDiff += printTimes(1000,100); - timeDiff += printTimes(1000,500); - timeDiff += printTimes(1000,1000); - Assert.assertTrue(timeDiff <= 0); - } - - 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++){ - output = (int[]) ArrayUtils.removeAll(array, toRemove); - } - 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); - output = (int[]) ArrayUtils.removeAll((Object)array, extractIndices); - } - final long end = System.nanoTime(); - Assert.assertEquals(array.length-toRemove.cardinality(), output.length); - return end - start; - } - -} \ No newline at end of file +}