This is an automated email from the ASF dual-hosted git repository.

zabetak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new f33e1b8  [CALCITE-2902] Improve performance of 
AbstractRelNode#computeDigest
f33e1b8 is described below

commit f33e1b8f5609f11b039577694023241156951c08
Author: Stamatis Zampetakis <zabe...@gmail.com>
AuthorDate: Fri Mar 8 18:56:44 2019 +0100

    [CALCITE-2902] Improve performance of AbstractRelNode#computeDigest
    
    1. Use StringBuilder instead of PrintWriter for building the digest, which 
is more efficient to initialize and append to.
    2. Improve (sligthly) the performance of AbstractRelNode#getRelTypeName 
(used in the digest) by performing:
    a. one lastIndexOf operation instead of potentially two;
    b. char instead of char[] array comparison.
    3. Add micro benchmark with different implementations of 
AbstractRelNode#getRelTypeName showing the benefit of the adopted 
implementation.
    4. Improve RelWriter interface with default methods and refactor respective 
classes.
---
 .../org/apache/calcite/rel/AbstractRelNode.java    | 117 +++++----
 .../java/org/apache/calcite/rel/RelWriter.java     |  12 +-
 .../calcite/rel/externalize/RelJsonWriter.java     |  13 +-
 .../calcite/rel/externalize/RelWriterImpl.java     |  16 --
 .../AbstractRelNodeGetRelTypeNameBenchmark.java    | 261 +++++++++++++++++++++
 5 files changed, 340 insertions(+), 79 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java 
b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
index 59a9179..f4899a1 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -27,7 +27,6 @@ import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.plan.RelTrait;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.core.CorrelationId;
-import org.apache.calcite.rel.externalize.RelWriterImpl;
 import org.apache.calcite.rel.metadata.Metadata;
 import org.apache.calcite.rel.metadata.MetadataFactory;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
@@ -46,8 +45,6 @@ import com.google.common.collect.ImmutableSet;
 
 import org.slf4j.Logger;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -190,16 +187,14 @@ public abstract class AbstractRelNode implements RelNode {
   }
 
   public final String getRelTypeName() {
-    String className = getClass().getName();
-    int i = className.lastIndexOf("$");
-    if (i >= 0) {
-      return className.substring(i + 1);
-    }
-    i = className.lastIndexOf(".");
-    if (i >= 0) {
-      return className.substring(i + 1);
+    String cn = getClass().getName();
+    int i = cn.length();
+    while (--i >= 0) {
+      if (cn.charAt(i) == '$' || cn.charAt(i) == '.') {
+        return cn.substring(i + 1);
+      }
     }
-    return className;
+    return cn;
   }
 
   public boolean isValid(Litmus litmus, Context context) {
@@ -389,42 +384,68 @@ public abstract class AbstractRelNode implements RelNode {
    * @return Digest
    */
   protected String computeDigest() {
-    StringWriter sw = new StringWriter();
-    RelWriter pw =
-        new RelWriterImpl(
-            new PrintWriter(sw),
-            SqlExplainLevel.DIGEST_ATTRIBUTES, false) {
-          protected void explain_(
-              RelNode rel, List<Pair<String, Object>> values) {
-            pw.write(getRelTypeName());
-
-            for (RelTrait trait : traitSet) {
-              pw.write(".");
-              pw.write(trait.toString());
-            }
-
-            pw.write("(");
-            int j = 0;
-            for (Pair<String, Object> value : values) {
-              if (j++ > 0) {
-                pw.write(",");
-              }
-              pw.write(value.left);
-              pw.write("=");
-              if (value.right instanceof RelNode) {
-                RelNode input = (RelNode) value.right;
-                pw.write(input.getRelTypeName());
-                pw.write("#");
-                pw.write(Integer.toString(input.getId()));
-              } else {
-                pw.write(String.valueOf(value.right));
-              }
-            }
-            pw.write(")");
-          }
-        };
-    explain(pw);
-    return sw.toString();
+    RelDigestWriter rdw = new RelDigestWriter();
+    explain(rdw);
+    return rdw.digest;
+  }
+
+  /**
+   * A writer object used exclusively for computing the digest of a RelNode.
+   *
+   * <p>The writer is meant to be used only for computing a single digest and 
then thrown away.
+   * After calling {@link #done(RelNode)} the writer should be used only to 
obtain the computed
+   * {@link #digest}. Any other action is prohibited.</p>
+   *
+   */
+  private static final class RelDigestWriter implements RelWriter {
+
+    private final List<Pair<String, Object>> values = new ArrayList<>();
+
+    String digest = null;
+
+    @Override public void explain(final RelNode rel, final List<Pair<String, 
Object>> valueList) {
+      throw new IllegalStateException("Should not be called for computing 
digest");
+    }
+
+    @Override public SqlExplainLevel getDetailLevel() {
+      return SqlExplainLevel.DIGEST_ATTRIBUTES;
+    }
+
+    @Override public RelWriter item(String term, Object value) {
+      values.add(Pair.of(term, value));
+      return this;
+    }
+
+    @Override public RelWriter done(RelNode node) {
+      StringBuilder sb = new StringBuilder();
+      sb.append(node.getRelTypeName());
+
+      for (RelTrait trait : node.getTraitSet()) {
+        sb.append('.');
+        sb.append(trait.toString());
+      }
+
+      sb.append('(');
+      int j = 0;
+      for (Pair<String, Object> value : values) {
+        if (j++ > 0) {
+          sb.append(',');
+        }
+        sb.append(value.left);
+        sb.append('=');
+        if (value.right instanceof RelNode) {
+          RelNode input = (RelNode) value.right;
+          sb.append(input.getRelTypeName());
+          sb.append('#');
+          sb.append(input.getId());
+        } else {
+          sb.append(value.right);
+        }
+      }
+      sb.append(')');
+      digest = sb.toString();
+      return this;
+    }
   }
 }
 
diff --git a/core/src/main/java/org/apache/calcite/rel/RelWriter.java 
b/core/src/main/java/org/apache/calcite/rel/RelWriter.java
index fa63bc2..551685c 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelWriter.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelWriter.java
@@ -53,7 +53,9 @@ public interface RelWriter {
    * @param term  Term for input, e.g. "left" or "input #1".
    * @param input Input relational expression
    */
-  RelWriter input(String term, RelNode input);
+  default RelWriter input(String term, RelNode input) {
+    return item(term, input);
+  }
 
   /**
    * Adds an attribute to the explanation of the current node.
@@ -67,7 +69,9 @@ public interface RelWriter {
    * Adds an input to the explanation of the current node, if a condition
    * holds.
    */
-  RelWriter itemIf(String term, Object value, boolean condition);
+  default RelWriter itemIf(String term, Object value, boolean condition) {
+    return condition ? item(term, value) : this;
+  }
 
   /**
    * Writes the completed explanation.
@@ -78,7 +82,9 @@ public interface RelWriter {
    * Returns whether the writer prefers nested values. Traditional explain
    * writers prefer flattened values.
    */
-  boolean nest();
+  default boolean nest() {
+    return false;
+  }
 }
 
 // End RelWriter.java
diff --git 
a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java 
b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
index fb96778..c2105cb 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
@@ -104,10 +104,6 @@ public class RelJsonWriter implements RelWriter {
     return SqlExplainLevel.ALL_ATTRIBUTES;
   }
 
-  public RelWriter input(String term, RelNode input) {
-    return this;
-  }
-
   public RelWriter item(String term, Object value) {
     values.add(Pair.of(term, value));
     return this;
@@ -125,13 +121,6 @@ public class RelJsonWriter implements RelWriter {
     return list;
   }
 
-  public RelWriter itemIf(String term, Object value, boolean condition) {
-    if (condition) {
-      item(term, value);
-    }
-    return this;
-  }
-
   public RelWriter done(RelNode node) {
     final List<Pair<String, Object>> valuesCopy =
         ImmutableList.copyOf(values);
@@ -140,7 +129,7 @@ public class RelJsonWriter implements RelWriter {
     return this;
   }
 
-  public boolean nest() {
+  @Override public boolean nest() {
     return true;
   }
 
diff --git 
a/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java 
b/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
index af2985e..9dade7b 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
@@ -131,23 +131,11 @@ public class RelWriterImpl implements RelWriter {
     return detailLevel;
   }
 
-  public RelWriter input(String term, RelNode input) {
-    values.add(Pair.of(term, (Object) input));
-    return this;
-  }
-
   public RelWriter item(String term, Object value) {
     values.add(Pair.of(term, value));
     return this;
   }
 
-  public RelWriter itemIf(String term, Object value, boolean condition) {
-    if (condition) {
-      item(term, value);
-    }
-    return this;
-  }
-
   public RelWriter done(RelNode node) {
     assert checkInputsPresentInExplain(node);
     final List<Pair<String, Object>> valuesCopy =
@@ -170,10 +158,6 @@ public class RelWriterImpl implements RelWriter {
     return true;
   }
 
-  public boolean nest() {
-    return false;
-  }
-
   /**
    * Converts the collected terms and values to a string. Does not write to
    * the parent writer.
diff --git 
a/ubenchmark/src/main/java/org/apache/calcite/benchmarks/AbstractRelNodeGetRelTypeNameBenchmark.java
 
b/ubenchmark/src/main/java/org/apache/calcite/benchmarks/AbstractRelNodeGetRelTypeNameBenchmark.java
new file mode 100644
index 0000000..3321881
--- /dev/null
+++ 
b/ubenchmark/src/main/java/org/apache/calcite/benchmarks/AbstractRelNodeGetRelTypeNameBenchmark.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.benchmarks;
+
+
+import org.apache.calcite.rel.AbstractRelNode;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A benchmark of alternative implementations for {@link 
AbstractRelNode#getRelTypeName()}
+ * method.
+ */
+@Fork(value = 1, jvmArgsPrepend = "-Xmx1024m")
+@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
+@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
+@Threads(1)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@BenchmarkMode(Mode.AverageTime)
+public class AbstractRelNodeGetRelTypeNameBenchmark {
+
+  /**
+   * A state holding the full class names of all built-in implementors of the
+   * {@link org.apache.calcite.rel.RelNode} interface.
+   */
+  @State(Scope.Thread)
+  public static class ClassNameState {
+
+    private final String[] fullNames = new String[]{
+        "org.apache.calcite.interpreter.InterpretableRel",
+        "org.apache.calcite.interpreter.BindableRel",
+        "org.apache.calcite.adapter.enumerable.EnumerableInterpretable",
+        "org.apache.calcite.adapter.enumerable.EnumerableRel",
+        "org.apache.calcite.adapter.enumerable.EnumerableLimit",
+        "org.apache.calcite.adapter.enumerable.EnumerableUnion",
+        "org.apache.calcite.adapter.enumerable.EnumerableCollect",
+        "org.apache.calcite.adapter.enumerable.EnumerableTableFunctionScan",
+        "org.apache.calcite.adapter.enumerable.EnumerableValues",
+        "org.apache.calcite.adapter.enumerable.EnumerableSemiJoin",
+        "org.apache.calcite.adapter.enumerable.EnumerableMinus",
+        "org.apache.calcite.adapter.enumerable.EnumerableIntersect",
+        "org.apache.calcite.adapter.enumerable.EnumerableUncollect",
+        "org.apache.calcite.adapter.enumerable.EnumerableMergeJoin",
+        "org.apache.calcite.adapter.enumerable.EnumerableProject",
+        "org.apache.calcite.adapter.enumerable.EnumerableFilter",
+        "org.apache.calcite.adapter.jdbc.JdbcToEnumerableConverter",
+        "org.apache.calcite.adapter.enumerable.EnumerableThetaJoin",
+        "org.apache.calcite.adapter.enumerable.EnumerableTableScan",
+        "org.apache.calcite.adapter.enumerable.EnumerableJoin",
+        "org.apache.calcite.adapter.enumerable.EnumerableTableModify",
+        "org.apache.calcite.adapter.enumerable.EnumerableAggregate",
+        "org.apache.calcite.adapter.enumerable.EnumerableCorrelate",
+        "org.apache.calcite.adapter.enumerable.EnumerableSort",
+        "org.apache.calcite.adapter.enumerable.EnumerableWindow",
+        "org.apache.calcite.plan.volcano.VolcanoPlannerTraitTest$FooRel",
+        "org.apache.calcite.adapter.enumerable.EnumerableCalc",
+        "org.apache.calcite.adapter.enumerable.EnumerableInterpreter",
+        "org.apache.calcite.adapter.geode.rel.GeodeToEnumerableConverter",
+        "org.apache.calcite.adapter.pig.PigToEnumerableConverter",
+        "org.apache.calcite.adapter.mongodb.MongoToEnumerableConverter",
+        "org.apache.calcite.adapter.csv.CsvTableScan",
+        "org.apache.calcite.adapter.spark.SparkToEnumerableConverter",
+        
"org.apache.calcite.adapter.elasticsearch.ElasticsearchToEnumerableConverter",
+        "org.apache.calcite.adapter.file.FileTableScan",
+        "org.apache.calcite.adapter.cassandra.CassandraToEnumerableConverter",
+        "org.apache.calcite.adapter.splunk.SplunkTableScan",
+        "org.apache.calcite.adapter.jdbc.JdbcRel",
+        "org.apache.calcite.adapter.jdbc.JdbcTableScan",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcJoin",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcCalc",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcProject",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcFilter",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcAggregate",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcSort",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcUnion",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcIntersect",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcMinus",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcTableModify",
+        "org.apache.calcite.adapter.jdbc.JdbcRules$JdbcValues",
+        "org.apache.calcite.tools.PlannerTest$MockJdbcTableScan",
+        "org.apache.calcite.rel.AbstractRelNode",
+        "org.apache.calcite.rel.rules.MultiJoin",
+        "org.apache.calcite.rel.core.TableFunctionScan",
+        "org.apache.calcite.rel.BiRel",
+        "org.apache.calcite.rel.SingleRel",
+        "org.apache.calcite.rel.core.Values",
+        "org.apache.calcite.rel.core.TableScan",
+        "org.apache.calcite.plan.hep.HepRelVertex",
+        "org.apache.calcite.plan.RelOptPlanReaderTest$MyRel",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$PhysTable",
+        "org.apache.calcite.plan.volcano.PlannerTests$TestLeafRel",
+        "org.apache.calcite.plan.volcano.RelSubset",
+        "org.apache.calcite.rel.core.SetOp",
+        "org.apache.calcite.plan.volcano.VolcanoPlannerTraitTest$TestLeafRel",
+        "org.apache.calcite.adapter.druid.DruidQuery",
+        
"org.apache.calcite.sql2rel.RelStructuredTypeFlattener$SelfFlatteningRel",
+        "org.apache.calcite.rel.convert.Converter",
+        "org.apache.calcite.rel.convert.ConverterImpl",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$Phys",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$PhysTable",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$PhysSort",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$PhysAgg",
+        "org.apache.calcite.plan.volcano.TraitPropagationTest$PhysProj",
+        "org.apache.calcite.interpreter.BindableRel",
+        "org.apache.calcite.adapter.enumerable.EnumerableBindable",
+        "org.apache.calcite.interpreter.Bindables$BindableTableScan",
+        "org.apache.calcite.interpreter.Bindables$BindableFilter",
+        "org.apache.calcite.interpreter.Bindables$BindableProject",
+        "org.apache.calcite.interpreter.Bindables$BindableSort",
+        "org.apache.calcite.interpreter.Bindables$BindableJoin",
+        "org.apache.calcite.interpreter.Bindables$BindableUnion",
+        "org.apache.calcite.interpreter.Bindables$BindableValues",
+        "org.apache.calcite.interpreter.Bindables$BindableAggregate",
+        "org.apache.calcite.interpreter.Bindables$BindableWindow",
+        "org.apache.calcite.adapter.druid.DruidQuery",
+        "org.apache.calcite.adapter.cassandra.CassandraRel",
+        "org.apache.calcite.adapter.cassandra.CassandraFilter",
+        "org.apache.calcite.adapter.cassandra.CassandraProject",
+        "org.apache.calcite.adapter.cassandra.CassandraLimit",
+        "org.apache.calcite.adapter.cassandra.CassandraSort",
+        "org.apache.calcite.adapter.cassandra.CassandraTableScan",
+        "org.apache.calcite.adapter.mongodb.MongoRel",
+        "org.apache.calcite.adapter.mongodb.MongoTableScan",
+        "org.apache.calcite.adapter.mongodb.MongoProject",
+        "org.apache.calcite.adapter.mongodb.MongoFilter",
+        "org.apache.calcite.adapter.mongodb.MongoAggregate",
+        "org.apache.calcite.adapter.mongodb.MongoSort",
+        "org.apache.calcite.adapter.spark.SparkRel",
+        "org.apache.calcite.adapter.spark.JdbcToSparkConverter",
+        "org.apache.calcite.adapter.spark.SparkRules$SparkValues",
+        "org.apache.calcite.adapter.spark.EnumerableToSparkConverter",
+        "org.apache.calcite.adapter.spark.SparkRules$SparkCalc",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchRel",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchFilter",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchProject",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchAggregate",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchTableScan",
+        "org.apache.calcite.adapter.elasticsearch.ElasticsearchSort",
+        "org.apache.calcite.adapter.geode.rel.GeodeRel",
+        "org.apache.calcite.adapter.geode.rel.GeodeSort",
+        "org.apache.calcite.adapter.geode.rel.GeodeTableScan",
+        "org.apache.calcite.adapter.geode.rel.GeodeProject",
+        "org.apache.calcite.adapter.geode.rel.GeodeFilter",
+        "org.apache.calcite.adapter.geode.rel.GeodeAggregate",
+        "org.apache.calcite.adapter.pig.PigRel",
+        "org.apache.calcite.adapter.pig.PigTableScan",
+        "org.apache.calcite.adapter.pig.PigAggregate",
+        "org.apache.calcite.adapter.pig.PigJoin",
+        "org.apache.calcite.adapter.pig.PigFilter",
+        "org.apache.calcite.adapter.pig.PigProject"
+    };
+
+    @Param({"11", "31", "63"})
+    private long seed;
+
+    private Random r = null;
+
+    /**
+     * Setups the random number generator at the beginning of each iteration.
+     *
+     * To have relatively comparable results the generator should always use 
the same seed for the
+     * whole duration of the benchmark.
+     */
+    @Setup(Level.Iteration)
+    public void setupRandom() {
+      r = new Random(seed);
+    }
+
+    /**
+     * Returns a pseudo random class name which corresponds to an implementor 
of the RelNode
+     * interface.
+     */
+    public String nextName() {
+      return fullNames[r.nextInt(fullNames.length)];
+    }
+  }
+
+  @Benchmark
+  public String useStringLastIndexOfTwoTimesV1(ClassNameState state) {
+    String cn = state.nextName();
+    int i = cn.lastIndexOf("$");
+    if (i >= 0) {
+      return cn.substring(i + 1);
+    }
+    i = cn.lastIndexOf(".");
+    if (i >= 0) {
+      return cn.substring(i + 1);
+    }
+    return cn;
+  }
+
+  @Benchmark
+  public String useStringLastIndexOfTwoTimeV2(ClassNameState state) {
+    String cn = state.nextName();
+    int i = cn.lastIndexOf('$');
+    if (i >= 0) {
+      return cn.substring(i + 1);
+    }
+    i = cn.lastIndexOf('.');
+    if (i >= 0) {
+      return cn.substring(i + 1);
+    }
+    return cn;
+  }
+
+  @Benchmark
+  public String useCustomLastIndexOf(ClassNameState state) {
+    String cn = state.nextName();
+    int i = cn.length();
+    while (--i >= 0) {
+      if (cn.charAt(i) == '$' || cn.charAt(i) == '.') {
+        return cn.substring(i + 1);
+      }
+    }
+    return cn;
+  }
+
+  public static void main(String[] args) throws RunnerException {
+    Options opt = new OptionsBuilder()
+        .include(AbstractRelNodeGetRelTypeNameBenchmark.class.getName())
+        .detectJvmArgs()
+        .build();
+
+    new Runner(opt).run();
+  }
+}
+
+// End AbstractRelNodeGetRelTypeNameBenchmark.java

Reply via email to