From d2a22954cb6584110cfcb0630cedb1f8c3bbc7ac Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Wed, 18 Mar 2026 09:12:14 -0400 Subject: [PATCH 1/3] List iteration benchmark --- .../trace/util/ListIterationBenchmark.java | 412 ++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 internal-api/src/jmh/java/datadog/trace/util/ListIterationBenchmark.java diff --git a/internal-api/src/jmh/java/datadog/trace/util/ListIterationBenchmark.java b/internal-api/src/jmh/java/datadog/trace/util/ListIterationBenchmark.java new file mode 100644 index 00000000000..c32b924864a --- /dev/null +++ b/internal-api/src/jmh/java/datadog/trace/util/ListIterationBenchmark.java @@ -0,0 +1,412 @@ +package datadog.trace.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.CompilerControl.Mode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +/** + * Benchmark comparing difference ways to iterate list of different types and sizes -- both with + * simple loop bodies (inline case) and complicated loop bodies (dont inline case). + * + * + * Java 17 - MacBook M1 - 8 threads * Benchmark (listSpec) Mode Cnt Score Error Units * ListIterationBenchmark.cstyleFor_inline COLLECTIONS_EMPTY_LIST thrpt 3 9066154714.207 ± 3993855570.335 ops/s * ListIterationBenchmark.cstyleFor:gc.alloc.rate.norm COLLECTIONS_EMPTY_LIST thrpt 3 ≈ 10⁻⁷ B/op @@ -335,75 +337,74 @@ public enum ListSpec { @Param ListSpec listSpec; - @Benchmark - public void forEach_inline() { - this.listSpec.list.forEach(Element::manipulate_inline); - } - - @Benchmark - public void forEach_dont_inline() { - this.listSpec.list.forEach(Element::manipulate_dont_inline); - } - - @Benchmark - public void enhancedFor_inline() { - // Enhanced for-loop is just syntax sugar for an Iterator - for ( Element e : this.listSpec.list ) { - e.manipulate_inline(); - } - } - - @Benchmark - public void enhancedFor_dont_inline() { - // Enhanced for-loop is just syntax sugar for an Iterator - for ( Element e : this.listSpec.list ) { - e.manipulate_dont_inline(); - } - } - - @Benchmark - public void iterator_inline() { - for ( Iterator iter = this.listSpec.list.iterator(); iter.hasNext(); ) { - iter.next().manipulate_inline(); - } - } - - @Benchmark - public void iterator_dont_inline() { - for ( Iterator iter = this.listSpec.list.iterator(); iter.hasNext(); ) { - iter.next().manipulate_dont_inline(); - } + @Benchmark + public void forEach_inline() { + this.listSpec.list.forEach(Element::manipulate_inline); + } + + @Benchmark + public void forEach_dont_inline() { + this.listSpec.list.forEach(Element::manipulate_dont_inline); + } + + @Benchmark + public void enhancedFor_inline() { + // Enhanced for-loop is just syntax sugar for an Iterator + for (Element e : this.listSpec.list) { + e.manipulate_inline(); } - - - @Benchmark - public void cstyleFor_inline() { - for ( int i = 0; i < this.listSpec.list.size(); ++i ) { - this.listSpec.list.get(i).manipulate_inline(); - } + } + + @Benchmark + public void enhancedFor_dont_inline() { + // Enhanced for-loop is just syntax sugar for an Iterator + for (Element e : this.listSpec.list) { + e.manipulate_dont_inline(); } - - @Benchmark - public void cstyleFor_dont_inline() { - for ( int i = 0; i < this.listSpec.list.size(); ++i ) { - this.listSpec.list.get(i).manipulate_dont_inline(); - } + } + + @Benchmark + public void iterator_inline() { + for (Iterator iter = this.listSpec.list.iterator(); iter.hasNext(); ) { + iter.next().manipulate_inline(); } - - @Benchmark - public void streams_inline() { - this.listSpec.list.stream().forEach(Element::manipulate_inline); + } + + @Benchmark + public void iterator_dont_inline() { + for (Iterator iter = this.listSpec.list.iterator(); iter.hasNext(); ) { + iter.next().manipulate_dont_inline(); } - - @Benchmark - public void streams_dont_inline() { - this.listSpec.list.stream().forEach(Element::manipulate_dont_inline); + } + + @Benchmark + public void cstyleFor_inline() { + for (int i = 0; i < this.listSpec.list.size(); ++i) { + this.listSpec.list.get(i).manipulate_inline(); } - - @Benchmark - public void parallelStreams_inline() { - listSpec.list.parallelStream().forEach(Element::manipulate_dont_inline); + } + + @Benchmark + public void cstyleFor_dont_inline() { + for (int i = 0; i < this.listSpec.list.size(); ++i) { + this.listSpec.list.get(i).manipulate_dont_inline(); } + } + + @Benchmark + public void streams_inline() { + this.listSpec.list.stream().forEach(Element::manipulate_inline); + } + + @Benchmark + public void streams_dont_inline() { + this.listSpec.list.stream().forEach(Element::manipulate_dont_inline); + } + + @Benchmark + public void parallelStreams_inline() { + listSpec.list.parallelStream().forEach(Element::manipulate_dont_inline); + } @Benchmark public void parallelStreams_dont_inline() {