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 <jde...@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; + } +}