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

jin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git


The following commit(s) were added to refs/heads/master by this push:
     new 5df28fa2c feat(perf): support JMH benchmark in HG-test module (#2238)
5df28fa2c is described below

commit 5df28fa2cafd9607edd746c78219e65649d55667
Author: conghuhu <[email protected]>
AuthorDate: Mon Jul 17 16:50:35 2023 +0800

    feat(perf): support JMH benchmark in HG-test module (#2238)
    
    * chore: add param to max cap
    
    * chore: add non argument constructor to IntMapByEcSegment
    
    ---------
    
    Co-authored-by: shiyi <[email protected]>
---
 .../apache/hugegraph/util/collection/IntMap.java   |   6 +-
 hugegraph-dist/release-docs/LICENSE                |   1 +
 .../release-docs/licenses/LINCENSE-jopt-simple.txt |  24 ++++
 hugegraph-test/pom.xml                             |  35 ++++++
 .../hugegraph/benchmark/BenchmarkConstants.java    |  23 ++++
 .../apache/hugegraph/benchmark/SimpleRandom.java   |  42 +++++++
 .../map/MapRandomGetPutThroughputTest.java         | 137 +++++++++++++++++++++
 pom.xml                                            |  14 ++-
 8 files changed, 280 insertions(+), 2 deletions(-)

diff --git 
a/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java 
b/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java
index 446582746..02b705225 100644
--- 
a/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java
+++ 
b/hugegraph-core/src/main/java/org/apache/hugegraph/util/collection/IntMap.java
@@ -68,7 +68,7 @@ public interface IntMap {
         private final int segmentMask;
         private final Function<Integer, IntMap> creator;
 
-        private static final int DEFAULT_SEGMENTS = IntSet.CPUS * 100;
+        private static final int DEFAULT_SEGMENTS = (IntSet.CPUS + 8) * 32;
         private static final Function<Integer, IntMap> DEFAULT_CREATOR =
                              size -> new IntMapByFixedAddr(size);
 
@@ -512,6 +512,10 @@ public interface IntMap {
         private final MutableIntIntMap[] maps;
         private final int segmentMask;
 
+        public IntMapByEcSegment() {
+            this(IntMapBySegments.DEFAULT_SEGMENTS);
+        }
+
         public IntMapByEcSegment(int segments) {
             segments = IntSet.sizeToPowerOf2Size(segments);
             this.segmentMask = segments - 1;
diff --git a/hugegraph-dist/release-docs/LICENSE 
b/hugegraph-dist/release-docs/LICENSE
index 5bfd9e606..f1cc9686c 100644
--- a/hugegraph-dist/release-docs/LICENSE
+++ b/hugegraph-dist/release-docs/LICENSE
@@ -539,6 +539,7 @@ See licenses/ for text of these licenses.
        (The MIT License) * mockito-core (org.mockito:mockito-core:3.3.3 - 
https://github.com/mockito/mockito)
        (The MIT License) * sourcecode (com.lihaoyi:sourcecode_2.12:0.1.4 - 
https://github.com/lihaoyi/sourcecode)
        (The MIT License) * Checker Qual 
(org.checkerframework:checker-qual:2.0.0 - http://checkerframework.org)
+       (The MIT License) * jopt-simple (net.sf.jopt-simple:jopt-simple:5.0.4 - 
https://github.com/jopt-simple/jopt-simple)
 
 ========================================================================
 Third party Public Domain licenses
diff --git a/hugegraph-dist/release-docs/licenses/LINCENSE-jopt-simple.txt 
b/hugegraph-dist/release-docs/licenses/LINCENSE-jopt-simple.txt
new file mode 100644
index 000000000..6984620c3
--- /dev/null
+++ b/hugegraph-dist/release-docs/licenses/LINCENSE-jopt-simple.txt
@@ -0,0 +1,24 @@
+/*
+ The MIT License
+
+ Copyright (c) 2004-2021 Paul R. Holser, Jr.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/hugegraph-test/pom.xml b/hugegraph-test/pom.xml
index 0bda198c4..75e8caf66 100644
--- a/hugegraph-test/pom.xml
+++ b/hugegraph-test/pom.xml
@@ -120,6 +120,20 @@
                 </exclusion>
             </exclusions>
         </dependency>
+
+        <!-- JMH -->
+        <dependency>
+            <groupId>org.openjdk.jmh</groupId>
+            <artifactId>jmh-core</artifactId>
+            <version>${jmh.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openjdk.jmh</groupId>
+            <artifactId>jmh-generator-annprocess</artifactId>
+            <version>${jmh.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -256,6 +270,27 @@
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <finalName>microbenchmarks</finalName>
+                            <transformers>
+                                <transformer
+                                    
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>org.openjdk.jmh.Main</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
 
         <resources>
diff --git 
a/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/BenchmarkConstants.java
 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/BenchmarkConstants.java
new file mode 100644
index 000000000..1525e8143
--- /dev/null
+++ 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/BenchmarkConstants.java
@@ -0,0 +1,23 @@
+/*
+ * 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.hugegraph.benchmark;
+
+public class BenchmarkConstants {
+
+    public static String OUTPUT_PATH = "./hugegraph-test/target/";
+}
diff --git 
a/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/SimpleRandom.java 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/SimpleRandom.java
new file mode 100644
index 000000000..3338f10af
--- /dev/null
+++ 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/SimpleRandom.java
@@ -0,0 +1,42 @@
+/*
+ * 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.hugegraph.benchmark;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Fairly fast random numbers
+ */
+public final class SimpleRandom {
+
+    private static final long MULTIPLIER = 0x5DEECE66DL;
+    private static final long ADD_END = 0xBL;
+    private static final long MASK = (1L << 48) - 1;
+    private static final AtomicLong SEG = new AtomicLong(-715159705);
+    private long seed;
+
+    public SimpleRandom() {
+        this.seed = System.nanoTime() + SEG.getAndAdd(129);
+    }
+
+    public int next() {
+        long nextSeed = (this.seed * MULTIPLIER + ADD_END) & MASK;
+        this.seed = nextSeed;
+        return ((int) (nextSeed >>> 17)) & 0x7FFFFFFF;
+    }
+}
diff --git 
a/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/map/MapRandomGetPutThroughputTest.java
 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/map/MapRandomGetPutThroughputTest.java
new file mode 100644
index 000000000..eafe4b861
--- /dev/null
+++ 
b/hugegraph-test/src/test/java/org/apache/hugegraph/benchmark/map/MapRandomGetPutThroughputTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.hugegraph.benchmark.map;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hugegraph.benchmark.BenchmarkConstants;
+import org.apache.hugegraph.benchmark.SimpleRandom;
+import org.apache.hugegraph.util.collection.IntMap;
+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.results.format.ResultFormatType;
+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;
+
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@BenchmarkMode({Mode.Throughput})
+@Warmup(iterations = 2, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 6, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+@Fork(2)
+public class MapRandomGetPutThroughputTest {
+
+    @Param(value = {"1000", "10000", "100000", "1000000"})
+    private int MAP_CAPACITY;
+
+    private ConcurrentHashMap<Integer, Integer> concurrentHashMapNonCap;
+
+    private ConcurrentHashMap<Integer, Integer> concurrentHashMap;
+
+    private IntMap.IntMapBySegments intMapBySegments;
+
+    private IntMap.IntMapByEcSegment intMapByEcSegments;
+
+    private static final int THREAD_COUNT = 8;
+
+    private static final String OUTPUT_FILE_NAME = 
"map_random_get_put_result.json";
+
+    @Setup(Level.Trial)
+    public void prepareMap() {
+        this.concurrentHashMapNonCap = new ConcurrentHashMap<>();
+        this.concurrentHashMap = new ConcurrentHashMap<>(MAP_CAPACITY);
+        this.intMapBySegments = new IntMap.IntMapBySegments(MAP_CAPACITY);
+        this.intMapByEcSegments = new IntMap.IntMapByEcSegment();
+    }
+
+    /**
+     * The instantiated @State annotation only supports public classes.
+     */
+    @State(Scope.Thread)
+    public static class ThreadState {
+
+        private final SimpleRandom random = new SimpleRandom();
+
+        int next() {
+            return random.next();
+        }
+    }
+
+    @Benchmark
+    @Threads(THREAD_COUNT)
+    public void randomGetPutOfConcurrentHashMapWithNoneInitCap(ThreadState 
state) {
+        int key = state.next() & (MAP_CAPACITY - 1);
+        if (!this.concurrentHashMapNonCap.containsKey(key)) {
+            this.concurrentHashMapNonCap.put(key, state.next());
+        }
+        this.concurrentHashMapNonCap.get(key);
+    }
+
+    @Benchmark
+    @Threads(THREAD_COUNT)
+    public void randomGetPutOfConcurrentHashMapWithInitCap(ThreadState state) {
+        int key = state.next() & (MAP_CAPACITY - 1);
+        if (!this.concurrentHashMap.containsKey(key)) {
+            this.concurrentHashMap.put(key, state.next());
+        }
+        this.concurrentHashMap.get(key);
+    }
+
+    @Benchmark
+    @Threads(THREAD_COUNT)
+    public void randomGetPutOfIntMapBySegments(ThreadState state) {
+        int key = state.next() & (MAP_CAPACITY - 1);
+        if (!this.intMapBySegments.containsKey(key)) {
+            this.intMapBySegments.put(key, state.next());
+        }
+        this.intMapBySegments.get(key);
+    }
+
+    @Benchmark
+    @Threads(THREAD_COUNT)
+    public void randomGetPutOfIntMapByEcSegment(ThreadState state) {
+        int key = state.next() & (MAP_CAPACITY - 1);
+        if (!this.intMapByEcSegments.containsKey(key)) {
+            this.intMapByEcSegments.put(key, state.next());
+        }
+        this.intMapByEcSegments.get(key);
+    }
+
+    public static void main(String[] args) throws RunnerException {
+        Options opt = new OptionsBuilder()
+            .include(MapRandomGetPutThroughputTest.class.getSimpleName())
+            .result(BenchmarkConstants.OUTPUT_PATH + OUTPUT_FILE_NAME)
+            .resultFormat(ResultFormatType.JSON)
+            .build();
+        new Runner(opt).run();
+    }
+}
diff --git a/pom.xml b/pom.xml
index 8679c83dd..719328316 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,6 +114,7 @@
         <hugegraph-commons.version>1.0.0</hugegraph-commons.version>
         <grpc.version>1.47.0</grpc.version>
         <protobuf.version>3.21.7</protobuf.version>
+        <jmh.version>1.36</jmh.version>
     </properties>
 
     <modules>
@@ -322,7 +323,18 @@
                 <artifactId>commons-text</artifactId>
                 <version>1.10.0</version>
             </dependency>
-
+            <dependency>
+                <groupId>org.openjdk.jmh</groupId>
+                <artifactId>jmh-core</artifactId>
+                <version>${jmh.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.openjdk.jmh</groupId>
+                <artifactId>jmh-generator-annprocess</artifactId>
+                <version>${jmh.version}</version>
+                <scope>test</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

Reply via email to