You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2022/04/06 20:57:51 UTC

[geode] branch develop updated: GEODE-10214: Improve speed of JvmSizeUtils.roundUpSize (#7548)

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

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 982f846fb5 GEODE-10214: Improve speed of JvmSizeUtils.roundUpSize (#7548)
982f846fb5 is described below

commit 982f846fb5d8b61e617c7d0e1a484ea0664229ab
Author: Jens Deppe <jd...@vmware.com>
AuthorDate: Wed Apr 6 13:57:46 2022 -0700

    GEODE-10214: Improve speed of JvmSizeUtils.roundUpSize (#7548)
    
    
    This small change improves the speed of this method by about 30% (as per
    basic JMH benchmarking). benchamrk1 is the original and benchmark2 the
    change.
    
    ```
    Benchmark                     Mode  Cnt     Score     Error  Units
    PerformanceSample.benchmark1  avgt    5  3480.815 ± 387.131  us/op
    PerformanceSample.benchmark2  avgt    5  2418.937 ± 586.209  us/op
    ```
---
 .../geode/internal/JvmSizeUtilsBenchmark.java      | 78 ++++++++++++++++++++++
 .../org/apache/geode/internal/JvmSizeUtils.java    | 13 ++--
 .../geode/internal/JvmSizeUtilsJUnitTest.java      | 38 +++++++++++
 3 files changed, 121 insertions(+), 8 deletions(-)

diff --git a/geode-core/src/jmh/java/org/apache/geode/internal/JvmSizeUtilsBenchmark.java b/geode-core/src/jmh/java/org/apache/geode/internal/JvmSizeUtilsBenchmark.java
new file mode 100644
index 0000000000..7756a28024
--- /dev/null
+++ b/geode-core/src/jmh/java/org/apache/geode/internal/JvmSizeUtilsBenchmark.java
@@ -0,0 +1,78 @@
+/*
+ * 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.geode.internal;
+
+import java.util.concurrent.TimeUnit;
+
+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.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Run this benchmark individually with:
+ * <br/>
+ * <code>
+ *    ./gradlew -Pjmh.include=JvmSizeUtilsBenchmark geode-core:jmh
+ * </code>
+ */
+@State(Scope.Thread)
+@Fork(1)
+public class JvmSizeUtilsBenchmark {
+
+  private int i = 0;
+
+  @TearDown(Level.Iteration)
+  public void teardown() {
+    i++;
+  }
+
+  @Benchmark
+  @Measurement(iterations = 5)
+  @Warmup(iterations = 3)
+  @BenchmarkMode(Mode.Throughput)
+  @OutputTimeUnit(TimeUnit.MILLISECONDS)
+  public long benchmark_roundUpSize() {
+    return JvmSizeUtils.roundUpSize(i);
+  }
+
+  @Benchmark
+  @Measurement(iterations = 5)
+  @Warmup(iterations = 3)
+  @BenchmarkMode(Mode.Throughput)
+  @OutputTimeUnit(TimeUnit.MILLISECONDS)
+  public long benchmark_old() {
+    return roundUpSize_old(i);
+  }
+
+  /**
+   * For reference, and to compare benchmark numbers, this is the original method.
+   */
+  private static long roundUpSize_old(long size) {
+    long remainder = size % 8;
+    if (remainder != 0) {
+      size += 8 - remainder;
+    }
+    return size;
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/JvmSizeUtils.java b/geode-core/src/main/java/org/apache/geode/internal/JvmSizeUtils.java
index 0731d8395e..673f1a0c55 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/JvmSizeUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/JvmSizeUtils.java
@@ -135,15 +135,12 @@ public class JvmSizeUtils {
     return objectHeaderSize;
   }
 
+  /**
+   * Round up to the nearest 8 bytes. Experimentally, this is what we've seen the sun 32 bit JVM do
+   * with object size.
+   */
   public static long roundUpSize(long size) {
-    // Round up to the nearest 8 bytes. Experimentally, this
-    // is what we've seen the sun 32 bit VM do with object size.
-    // See https://wiki.gemstone.com/display/rusage/Per+Entry+Overhead
-    long remainder = size % 8;
-    if (remainder != 0) {
-      size += 8 - remainder;
-    }
-    return size;
+    return ((size + 7) & (-8));
   }
 
   public static int roundUpSize(int size) {
diff --git a/geode-core/src/test/java/org/apache/geode/internal/JvmSizeUtilsJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/JvmSizeUtilsJUnitTest.java
new file mode 100644
index 0000000000..43adcadda8
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/JvmSizeUtilsJUnitTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.geode.internal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class JvmSizeUtilsJUnitTest {
+
+  @Test
+  public void roundUpSize() {
+    for (long i = 0; i < 1_000_000; i++) {
+      assertThat(JvmSizeUtils.roundUpSize(i)).isEqualTo(originalRoundUpSize(i));
+    }
+  }
+
+  private long originalRoundUpSize(long size) {
+    long remainder = size % 8;
+    if (remainder != 0) {
+      size += 8 - remainder;
+    }
+    return size;
+  }
+}