learned how to used Enclosed.class to have parameterized and non-parameterized sections of a test. I think all our Strategy tests should have a 'isFaster' test to ensure that our optimizations are actually making things faster. cc/ @dkuppitz.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/857deabf Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/857deabf Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/857deabf Branch: refs/heads/TINKERPOP-1254 Commit: 857deabf97582c4eb73b0f8f3edae3ea618831dd Parents: d634953 Author: Marko A. Rodriguez <[email protected]> Authored: Tue Jun 28 14:58:42 2016 -0600 Committer: Marko A. Rodriguez <[email protected]> Committed: Tue Jun 28 14:58:42 2016 -0600 ---------------------------------------------------------------------- .../IdentityRemovalStrategyTest.java | 103 ++++++----- .../optimization/RepeatUnrollStrategyTest.java | 181 ++++++++++--------- 2 files changed, 144 insertions(+), 140 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/857deabf/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java index c71ad99..3a84813 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java @@ -24,6 +24,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies; import org.apache.tinkerpop.gremlin.util.TimeUtil; import org.junit.Test; +import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -36,69 +37,71 @@ import static org.junit.Assert.assertTrue; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -@RunWith(Parameterized.class) +@RunWith(Enclosed.class) public class IdentityRemovalStrategyTest { - private static boolean executedshouldBeFaster = false; + @RunWith(Parameterized.class) + public static class ParameterizedTests { - @Parameterized.Parameter(value = 0) - public Traversal original; + @Parameterized.Parameter(value = 0) + public Traversal original; - @Parameterized.Parameter(value = 1) - public Traversal optimized; + @Parameterized.Parameter(value = 1) + public Traversal optimized; - private void applyIdentityRemovalStrategy(final Traversal traversal) { - final TraversalStrategies strategies = new DefaultTraversalStrategies(); - strategies.addStrategies(IdentityRemovalStrategy.instance()); - traversal.asAdmin().setStrategies(strategies); - traversal.asAdmin().applyStrategies(); + private void applyIdentityRemovalStrategy(final Traversal traversal) { + final TraversalStrategies strategies = new DefaultTraversalStrategies(); + strategies.addStrategies(IdentityRemovalStrategy.instance()); + traversal.asAdmin().setStrategies(strategies); + traversal.asAdmin().applyStrategies(); - } + } - @Test - public void doTest() { - applyIdentityRemovalStrategy(original); - assertEquals(optimized, original); - } + @Test + public void doTest() { + applyIdentityRemovalStrategy(original); + assertEquals(optimized, original); + } + + @Parameterized.Parameters(name = "{0}") + public static Iterable<Object[]> generateTestParameters() { + + return Arrays.asList(new Traversal[][]{ + {__.identity(), __.identity()}, + {__.identity().out(), __.out()}, + {__.identity().out().identity(), __.out()}, + {__.identity().as("a").out().identity(), __.identity().as("a").out()}, + {__.identity().as("a").out().identity().as("b"), __.identity().as("a").out().as("b")}, + {__.identity().as("a").out().in().identity().identity().as("b").identity().out(), __.identity().as("a").out().in().as("b").out()}, + {__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()}, + }); + } - @Parameterized.Parameters(name = "{0}") - public static Iterable<Object[]> generateTestParameters() { - - return Arrays.asList(new Traversal[][]{ - {__.identity(), __.identity()}, - {__.identity().out(), __.out()}, - {__.identity().out().identity(), __.out()}, - {__.identity().as("a").out().identity(), __.identity().as("a").out()}, - {__.identity().as("a").out().identity().as("b"), __.identity().as("a").out().as("b")}, - {__.identity().as("a").out().in().identity().identity().as("b").identity().out(), __.identity().as("a").out().in().as("b").out()}, - {__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()}, - }); } - @Test - public void shouldBeFaster() { - if (executedshouldBeFaster) - return; - else - executedshouldBeFaster = true; - final int startSize = 1000; - final int clockRuns = 1000; - final Integer[] starts = new Integer[startSize]; - for (int i = 0; i < startSize; i++) { - starts[i] = i; - } + public static class NonParameterizedTests { + @Test + public void shouldBeFaster() { - final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate(); + final int startSize = 1000; + final int clockRuns = 1000; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i; + } - final Runnable optimized = () -> { - final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity(); - traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance())); - traversal.iterate(); - }; + final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate(); - //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized)); - assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized)); - assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original)); + final Runnable optimized = () -> { + final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity(); + traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance())); + traversal.iterate(); + }; + + //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized)); + assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized)); + assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original)); + } } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/857deabf/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java index b819331..3d47a10 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java @@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.util.TimeUtil; import org.javatuples.Pair; import org.junit.Test; +import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -43,113 +44,113 @@ import static org.junit.Assert.assertTrue; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -@RunWith(Parameterized.class) + +@RunWith(Enclosed.class) public class RepeatUnrollStrategyTest { private static final Random RANDOM = new Random(); - private static boolean shouldBeFasterWithUniqueStreamExecuted = false; - private static boolean shouldBeFasterWithDuplicateStreamExecuted = false; - - @Parameterized.Parameter(value = 0) - public Traversal original; - @Parameterized.Parameter(value = 1) - public Traversal optimized; + @RunWith(Parameterized.class) + public static class ParameterizedTests { + @Parameterized.Parameter(value = 0) + public Traversal original; - private void applyRepeatUnrollStrategy(final Traversal traversal) { - final TraversalStrategies strategies = new DefaultTraversalStrategies(); - strategies.addStrategies(RepeatUnrollStrategy.instance()); - traversal.asAdmin().setStrategies(strategies); - traversal.asAdmin().applyStrategies(); + @Parameterized.Parameter(value = 1) + public Traversal optimized; - } - @Test - public void doTest() { - applyRepeatUnrollStrategy(original); - assertEquals(optimized, original); - } + private void applyRepeatUnrollStrategy(final Traversal traversal) { + final TraversalStrategies strategies = new DefaultTraversalStrategies(); + strategies.addStrategies(RepeatUnrollStrategy.instance()); + traversal.asAdmin().setStrategies(strategies); + traversal.asAdmin().applyStrategies(); - @Parameterized.Parameters(name = "{0}") - public static Iterable<Object[]> generateTestParameters() { - - final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5; - return Arrays.asList(new Traversal[][]{ - {__.identity(), __.identity()}, - {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()}, - {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()}, - {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()}, - {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()}, - {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()}, - {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()}, - {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()}, - {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()}, - {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")}, - {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)}, - {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)}, - {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()}, - {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()}, - {__.in().repeat(__.out("knows")).times(3).as("a").count().is(0), __.in().out("knows").barrier().out("knows").barrier().out("knows").as("a").count().is(0)}, - }); - } + } - @Test - public void shouldBeFasterWithUniqueStream() { - if (shouldBeFasterWithUniqueStreamExecuted) - return; - shouldBeFasterWithUniqueStreamExecuted = true; - final int startSize = 1000; - final int clockRuns = 1000; - final Integer[] starts = new Integer[startSize]; - for (int i = 0; i < startSize; i++) { - starts[i] = i; // 1000 unique objects + @Test + public void doTest() { + applyRepeatUnrollStrategy(original); + assertEquals(optimized, original); } - assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size()); - clockTraversals(starts, clockRuns); - } - @Test - public void shouldBeFasterWithDuplicateStream() { - if (shouldBeFasterWithDuplicateStreamExecuted) - return; - shouldBeFasterWithDuplicateStreamExecuted = true; - final int startSize = 1000; - final int clockRuns = 1000; - final int uniques = 100; - final Integer[] starts = new Integer[startSize]; - for (int i = 0; i < startSize; i++) { - starts[i] = i % uniques; // 100 unique objects + @Parameterized.Parameters(name = "{0}") + public static Iterable<Object[]> generateTestParameters() { + + final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5; + return Arrays.asList(new Traversal[][]{ + {__.identity(), __.identity()}, + {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()}, + {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()}, + {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()}, + {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()}, + {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()}, + {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()}, + {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()}, + {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()}, + {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")}, + {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)}, + {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)}, + {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()}, + {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()}, + {__.in().repeat(__.out("knows")).times(3).as("a").count().is(0), __.in().out("knows").barrier().out("knows").barrier().out("knows").as("a").count().is(0)}, + }); } - assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size()); - clockTraversals(starts, clockRuns); } - private void clockTraversals(final Integer[] starts, final int clockRuns) { - final int times = RANDOM.nextInt(4) + 2; - assertTrue(times > 1 && times < 6); - final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next(); + public static class NonParameterizedTests { + + @Test + public void shouldBeFasterWithUniqueStream() { + final int startSize = 1000; + final int clockRuns = 1000; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i; // 1000 unique objects + } + assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size()); + clockTraversals(starts, clockRuns); + } - final TraversalStrategies strategies = new DefaultTraversalStrategies(); - strategies.addStrategies(RepeatUnrollStrategy.instance()); - final Supplier<Long> optimized = () -> { - final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum(); - traversal.asAdmin().setStrategies(strategies); - return traversal.next(); - }; - - final Pair<Double, Long> originalResult; - final Pair<Double, Long> optimizedResult; - if (RANDOM.nextBoolean()) { - originalResult = TimeUtil.clockWithResult(clockRuns, original); - optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); - } else { - optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); - originalResult = TimeUtil.clockWithResult(clockRuns, original); + @Test + public void shouldBeFasterWithDuplicateStream() { + final int startSize = 1000; + final int clockRuns = 1000; + final int uniques = 100; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i % uniques; // 100 unique objects + } + assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size()); + clockTraversals(starts, clockRuns); } - // System.out.println(originalResult + "---" + optimizedResult); - assertEquals(originalResult.getValue1(), optimizedResult.getValue1()); - assertTrue(originalResult.getValue0() > optimizedResult.getValue0()); + private void clockTraversals(final Integer[] starts, final int clockRuns) { + final int times = RANDOM.nextInt(4) + 2; + assertTrue(times > 1 && times < 6); + final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next(); + + final TraversalStrategies strategies = new DefaultTraversalStrategies(); + strategies.addStrategies(RepeatUnrollStrategy.instance()); + final Supplier<Long> optimized = () -> { + final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum(); + traversal.asAdmin().setStrategies(strategies); + return traversal.next(); + }; + + final Pair<Double, Long> originalResult; + final Pair<Double, Long> optimizedResult; + if (RANDOM.nextBoolean()) { + originalResult = TimeUtil.clockWithResult(clockRuns, original); + optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); + } else { + optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); + originalResult = TimeUtil.clockWithResult(clockRuns, original); + } + + // System.out.println(originalResult + "---" + optimizedResult); + assertEquals(originalResult.getValue1(), optimizedResult.getValue1()); + assertTrue(originalResult.getValue0() > optimizedResult.getValue0()); + } } }
