8061281: Microbenchmark suite build support, directory layout and sample benchmarks
8061282: Migrate jmh-jdk-microbenchmarks into the JDK
Reviewed-by: ecaspole, mchung, erikj, ihse
Contributed-by: magnus.ihse.bursie@oracle.com, erik.joelsson@oracle.com, claes.redestad@oracle.com, sfriberg@kth.se
--- a/doc/testing.html Fri Nov 16 13:23:50 2018 -0500
+++ b/doc/testing.html Fri Nov 16 23:39:51 2018 +0100
@@ -24,12 +24,14 @@
<li><a href="#test-selection">Test selection</a><ul>
<li><a href="#jtreg">JTReg</a></li>
<li><a href="#gtest">Gtest</a></li>
+<li><a href="#microbenchmarks">Microbenchmarks</a></li>
<li><a href="#special-tests">Special tests</a></li>
</ul></li>
<li><a href="#test-results-and-summary">Test results and summary</a></li>
<li><a href="#test-suite-control">Test suite control</a><ul>
<li><a href="#jtreg-keywords">JTReg keywords</a></li>
<li><a href="#gtest-keywords">Gtest keywords</a></li>
+<li><a href="#microbenchmark-keywords">Microbenchmark keywords</a></li>
</ul></li>
</ul>
</nav>
@@ -44,9 +46,11 @@
$ make test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
$ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
+$ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
$ make exploded-test TEST=tier2</code></pre>
<h3 id="configuration">Configuration</h3>
<p>To be able to run JTReg tests, <code>configure</code> needs to know where to find the JTReg test framework. If it is not picked up automatically by configure, use the <code>--with-jtreg=<path to jtreg home></code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc. (An alternative is to set the <code>JT_HOME</code> environment variable to point to the JTReg home before running <code>configure</code>.)</p>
+<p>To be able to run microbenchmarks, <code>configure</code> needs to know where to find the JMH dependency. Use <code>--with-jmh=<path to JMH jars></code> to point to a directory containing the core JMH and transitive dependencies. The recommended dependencies can be retrieved by running <code>sh make/devkit/createJMHBundle.sh</code>, after which <code>--with-jmh=build/jmh/jars</code> should work.</p>
<h2 id="test-selection">Test selection</h2>
<p>All functionality is available using the <code>test</code> make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, <code>test-only</code> can be used instead, which do not depend on the source and test image build.</p>
<p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST="tier1"</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST="x"</code> solution needs to be used.</p>
@@ -61,6 +65,9 @@
<p>Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just <code>gtest</code>, or as a fully qualified test descriptor <code>gtest:all</code>.</p>
<p>If you want, you can single out an individual test or a group of tests, for instance <code>gtest:LogDecorations</code> or <code>gtest:LogDecorations.level_test_vm</code>. This can be particularly useful if you want to run a shaky test repeatedly.</p>
<p>For Gtest, there is a separate test suite for each JVM variant. The JVM variant is defined by adding <code>/<variant></code> to the test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no variant, gtest will run once for each JVM variant present (e.g. server, client). So if you only have the server JVM present, then <code>gtest:all</code> will be equivalent to <code>gtest:all/server</code>.</p>
+<h3 id="microbenchmarks">Microbenchmarks</h3>
+<p>Which microbenchmarks to run is selected using a regular expression following the <code>micro:</code> test descriptor, e.g., <code>micro:java.lang.reflect</code>. This delegates the test selection to JMH, meaning package name, class name and even benchmark method names can be used to select tests.</p>
+<p>Using special characters like <code>|</code> in the regular expression is possible, but needs to be escaped multiple times: <code>micro:ArrayCopy\\\\\|reflect</code>.</p>
<h3 id="special-tests">Special tests</h3>
<p>A handful of odd tests that are not covered by any other testing framework are accessible using the <code>special:</code> test descriptor. Currently, this includes <code>failure-handler</code> and <code>make</code>.</p>
<ul>
@@ -127,5 +134,22 @@
<h4 id="options-1">OPTIONS</h4>
<p>Additional options to the Gtest test framework.</p>
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest options.</p>
+<h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
+<h4 id="fork">FORK</h4>
+<p>Override the number of benchmark forks to spawn. Same as specifying <code>-f <num></code>.</p>
+<h4 id="iter">ITER</h4>
+<p>Number of measurement iterations per fork. Same as specifying <code>-i <num></code>.</p>
+<h4 id="time">TIME</h4>
+<p>Amount of time to spend in each measurement iteration, in seconds. Same as specifying <code>-r <num></code></p>
+<h4 id="warmup_iter">WARMUP_ITER</h4>
+<p>Number of warmup iterations to run before the measurement phase in each fork. Same as specifying <code>-wi <num></code>.</p>
+<h4 id="warmup_time">WARMUP_TIME</h4>
+<p>Amount of time to spend in each warmup iteration. Same as specifying <code>-w <num></code>.</p>
+<h4 id="results_format">RESULTS_FORMAT</h4>
+<p>Specify to have the test run save a log of the values. Accepts the same values as <code>-rff</code>, i.e., <code>text</code>, <code>csv</code>, <code>scsv</code>, <code>json</code>, or <code>latex</code>.</p>
+<h4 id="vm_options-1">VM_OPTIONS</h4>
+<p>Additional VM arguments to provide to forked off VMs. Same as <code>-jvmArgs <args></code></p>
+<h4 id="options-2">OPTIONS</h4>
+<p>Additional arguments to send to JMH.</p>
</body>
</html>
--- a/doc/testing.md Fri Nov 16 13:23:50 2018 -0500
+++ b/doc/testing.md Fri Nov 16 23:39:51 2018 +0100
@@ -26,6 +26,7 @@
$ make test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
$ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
+ $ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
$ make exploded-test TEST=tier2
### Configuration
@@ -37,6 +38,12 @@
containing `lib/jtreg.jar` etc. (An alternative is to set the `JT_HOME`
environment variable to point to the JTReg home before running `configure`.)
+To be able to run microbenchmarks, `configure` needs to know where to find
+the JMH dependency. Use `--with-jmh=<path to JMH jars>` to point to a directory
+containing the core JMH and transitive dependencies. The recommended dependencies
+can be retrieved by running `sh make/devkit/createJMHBundle.sh`, after which
+`--with-jmh=build/jmh/jars` should work.
+
## Test selection
All functionality is available using the `test` make target. In this use case,
@@ -104,6 +111,16 @@
variant present (e.g. server, client). So if you only have the server JVM
present, then `gtest:all` will be equivalent to `gtest:all/server`.
+### Microbenchmarks
+
+Which microbenchmarks to run is selected using a regular expression
+following the `micro:` test descriptor, e.g., `micro:java.lang.reflect`. This
+delegates the test selection to JMH, meaning package name, class name and even
+benchmark method names can be used to select tests.
+
+Using special characters like `|` in the regular expression is possible, but
+needs to be escaped multiple times: `micro:ArrayCopy\\\\\|reflect`.
+
### Special tests
A handful of odd tests that are not covered by any other testing framework are
@@ -253,6 +270,35 @@
Use `GTEST="OPTIONS=--help"` to see all available Gtest options.
+### Microbenchmark keywords
+
+#### FORK
+Override the number of benchmark forks to spawn. Same as specifying `-f <num>`.
+
+#### ITER
+Number of measurement iterations per fork. Same as specifying `-i <num>`.
+
+#### TIME
+Amount of time to spend in each measurement iteration, in seconds. Same as
+specifying `-r <num>`
+
+#### WARMUP_ITER
+Number of warmup iterations to run before the measurement phase in each fork.
+Same as specifying `-wi <num>`.
+
+#### WARMUP_TIME
+Amount of time to spend in each warmup iteration. Same as specifying `-w <num>`.
+
+#### RESULTS_FORMAT
+Specify to have the test run save a log of the values. Accepts the same values
+as `-rff`, i.e., `text`, `csv`, `scsv`, `json`, or `latex`.
+
+#### VM_OPTIONS
+Additional VM arguments to provide to forked off VMs. Same as `-jvmArgs <args>`
+
+#### OPTIONS
+Additional arguments to send to JMH.
+
---
# Override some definitions in the global css file that are not optimal for
# this document.
--- a/make/Help.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/Help.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -103,6 +103,7 @@
$(info $(_) # make test TEST="jdk_lang gtest:all")
$(info $(_) JTREG="OPT1=x;OPT2=y" # Control the JTREG test harness)
$(info $(_) GTEST="OPT1=x;OPT2=y" # Control the GTEST test harness)
+ $(info $(_) MICRO="OPT1=x;OPT2=y" # Control the MICRO test harness)
$(info $(_) TEST_OPTS="OPT1=x;..." # Generic control of all test harnesses)
$(info $(_) TEST_VM_OPTS="ARG ..." # Same as setting TEST_OPTS to VM_OPTIONS="ARG ...")
$(info )
--- a/make/InitSupport.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/InitSupport.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -50,7 +50,7 @@
# Make control variables, handled by Init.gmk
INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \
- COMPARE_BUILD JTREG GTEST TEST_OPTS TEST_VM_OPTS
+ COMPARE_BUILD JTREG GTEST MICRO TEST_OPTS TEST_VM_OPTS
# All known make control variables
MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
--- a/make/Main.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/Main.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -493,7 +493,7 @@
ALL_TARGETS += $(ALL_TEST_TARGETS) $(ALL_EXPLODED_TEST_TARGETS)
################################################################################
-# Build tests
+# Build tests and microbenchmarks
#
prepare-test-image:
@@ -543,11 +543,15 @@
-f BuildFailureHandler.gmk images)
endif
+build-microbenchmark:
+ +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f test/BuildMicrobenchmark.gmk)
+
ALL_TARGETS += prepare-test-image build-test-hotspot-jtreg-native \
test-image-hotspot-jtreg-native build-test-jdk-jtreg-native \
test-image-jdk-jtreg-native build-test-lib build-test-failure-handler \
test-failure-handler test-image-failure-handler test-image-hotspot-gtest \
- test-image-hotspot-jtreg-graal build-test-hotspot-jtreg-graal
+ test-image-hotspot-jtreg-graal build-test-hotspot-jtreg-graal \
+ build-microbenchmark
################################################################################
# Run tests
@@ -789,6 +793,8 @@
jrtfs-jar: interim-langtools
+ build-microbenchmark: interim-langtools jdk.unsupported java.management
+
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
ifeq ($(CREATE_BUILDJDK), true)
# If creating a buildjdk, the interim image needs to be based on that.
@@ -1023,6 +1029,10 @@
test-image-jdk-jtreg-native test-image-failure-handler \
test-image-demos-jdk $(JVM_TEST_IMAGE_TARGETS)
+ifneq ($(JMH_CORE_JAR), )
+ test-image: build-microbenchmark
+endif
+
################################################################################
# all-images builds all our deliverables as images.
--- a/make/RunTests.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/RunTests.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -237,13 +237,11 @@
$(info Running tests using TEST_OPTS control variable '$(TEST_OPTS)')
endif
+### Jtreg
+
$(eval $(call SetTestOpt,VM_OPTIONS,JTREG))
$(eval $(call SetTestOpt,JAVA_OPTIONS,JTREG))
-$(eval $(call SetTestOpt,VM_OPTIONS,GTEST))
-$(eval $(call SetTestOpt,JAVA_OPTIONS,GTEST))
-
$(eval $(call SetTestOpt,AOT_MODULES,JTREG))
-$(eval $(call SetTestOpt,AOT_MODULES,GTEST))
$(eval $(call SetTestOpt,JOBS,JTREG))
$(eval $(call SetTestOpt,TIMEOUT_FACTOR,JTREG))
@@ -259,6 +257,12 @@
$(info Running tests using JTREG control variable '$(JTREG)')
endif
+### Gtest
+
+$(eval $(call SetTestOpt,VM_OPTIONS,GTEST))
+$(eval $(call SetTestOpt,JAVA_OPTIONS,GTEST))
+$(eval $(call SetTestOpt,AOT_MODULES,GTEST))
+
$(eval $(call ParseKeywordVariable, GTEST, \
SINGLE_KEYWORDS := REPEAT AOT_MODULES, \
STRING_KEYWORDS := OPTIONS VM_OPTIONS JAVA_OPTIONS, \
@@ -269,6 +273,21 @@
$(info Running tests using GTEST control variable '$(GTEST)')
endif
+### Microbenchmarks
+
+$(eval $(call SetTestOpt,VM_OPTIONS,MICRO))
+$(eval $(call SetTestOpt,JAVA_OPTIONS,MICRO))
+
+$(eval $(call ParseKeywordVariable, MICRO, \
+ SINGLE_KEYWORDS := ITER FORK TIME WARMUP_ITER WARMUP_TIME, \
+ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS RESULTS_FORMAT TEST_JDK BENCHMARKS_JAR, \
+))
+
+ifneq ($(MICRO), )
+ # Inform the user
+ $(info Running tests using MICRO control variable '$(MICRO)')
+endif
+
################################################################################
# Component-specific Jtreg settings
@@ -325,6 +344,24 @@
)
endef
+# Helper function to determine if a test specification is a microbenchmark test
+#
+# It is a microbenchmark test if it is either "micro", or "micro:" followed by an optional
+# test filter string.
+define ParseMicroTestSelection
+ $(if $(filter micro%, $1), \
+ $(if $(filter micro, $1), \
+ micro:all \
+ , \
+ $(if $(filter micro:, $1), \
+ micro:all \
+ , \
+ $1 \
+ ) \
+ ) \
+ )
+endef
+
# Helper function that removes the TOPDIR part
CleanupJtregPath = \
$(strip $(patsubst %/, %, $(subst $(JTREG_TOPDIR)/,, $1)))
@@ -438,6 +475,9 @@
$(eval PARSED_TESTS += $(call ParseGtestTestSelection, $(test))) \
) \
$(if $(strip $(PARSED_TESTS)), , \
+ $(eval PARSED_TESTS += $(call ParseMicroTestSelection, $(test))) \
+ ) \
+ $(if $(strip $(PARSED_TESTS)), , \
$(eval PARSED_TESTS += $(call ParseJtregTestSelection, $(test))) \
) \
$(if $(strip $(PARSED_TESTS)), , \
@@ -560,6 +600,113 @@
################################################################################
+### Rules for Microbenchmarks
+
+# Helper function for SetupRunMicroTest. Set a MICRO_* variable from, in order:
+# 1) Specified by user on command line
+# 2) Generic default
+#
+# Note: No spaces are allowed around the arguments.
+# Arg $1 The test ID (i.e. $1 in SetupRunMicroTest)
+# Arg $2 Base variable, e.g. MICRO_TEST_JDK
+# Arg $3 The default value (optional)
+define SetMicroValue
+ ifneq ($$($2), )
+ $1_$2 := $$($2)
+ else
+ ifneq ($3, )
+ $1_$2 := $3
+ endif
+ endif
+endef
+
+SetupRunMicroTest = $(NamedParamsMacroTemplate)
+define SetupRunMicroTestBody
+ $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
+ $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
+ $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt
+
+ $1_TEST_NAME := $$(strip $$(patsubst micro:%, %, $$($1_TEST)))
+
+ $$(eval $$(call SetMicroValue,$1,MICRO_BENCHMARKS_JAR,$$(TEST_IMAGE_DIR)/micro/benchmarks.jar))
+ $$(eval $$(call SetMicroValue,$1,MICRO_TEST_JDK,$$(JDK_IMAGE_DIR)))
+ $$(eval $$(call SetMicroValue,$1,MICRO_JAVA_OPTIONS))
+
+ # Current tests needs to open java.io
+ $1_MICRO_JAVA_OPTIONS += --add-opens=java.base/java.io=ALL-UNNAMED
+
+ # Save output as JSON or CSV file
+ ifneq ($$(MICRO_RESULTS_FORMAT), )
+ $1_MICRO_BASIC_OPTIONS += -rf $$(MICRO_RESULTS_FORMAT) -rff $$($1_TEST_RESULTS_DIR)/jmh-result.$(MICRO_RESULTS_FORMAT)
+ endif
+
+ ifneq ($$(MICRO_VM_OPTIONS)$$(MICRO_JAVA_OPTIONS), )
+ $1_MICRO_VM_OPTIONS := -jvmArgs $$(MICRO_VM_OPTIONS) $$(MICRO_JAVA_OPTIONS)
+ endif
+
+ ifneq ($$(MICRO_ITER), )
+ $1_MICRO_ITER := -i $$(MICRO_ITER)
+ endif
+ ifneq ($$(MICRO_FORK), )
+ $1_MICRO_FORK := -f $$(MICRO_FORK)
+ endif
+ ifneq ($$(MICRO_TIME), )
+ $1_MICRO_TIME := -r $$(MICRO_TIME)
+ endif
+ ifneq ($$(MICRO_WARMUP_ITER), )
+ $1_MICRO_WARMUP_ITER := -wi $$(MICRO_WARMUP_ITER)
+ endif
+ ifneq ($$(MICRO_WARMUP_TIME), )
+ $1_MICRO_WARMUP_TIME := -w $$(MICRO_WARMUP_TIME)
+ endif
+
+ run-test-$1:
+ $$(call LogWarn)
+ $$(call LogWarn, Running test '$$($1_TEST)')
+ $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
+ $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/micro, \
+ $$($1_MICRO_TEST_JDK)/bin/java $$($1_MICRO_JAVA_OPTIONS) -jar $$($1_MICRO_BENCHMARKS_JAR) \
+ $$($1_MICRO_ITER) $$($1_MICRO_FORK) $$($1_MICRO_TIME) \
+ $$($1_MICRO_WARMUP_ITER) $$($1_MICRO_WARMUP_TIME) \
+ $$($1_MICRO_VM_OPTIONS) $$($1_MICRO_BASIC_OPTIONS) $$(MICRO_OPTIONS) \
+ $$($1_TEST_NAME) \
+ > >($(TEE) $$($1_TEST_RESULTS_DIR)/micro.txt) \
+ && $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ || $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ )
+
+ $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/micro.txt
+
+ parse-test-$1: run-test-$1
+ $$(call LogWarn, Finished running test '$$($1_TEST)')
+ $$(call LogWarn, Test report is stored in $$(strip \
+ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
+ $$(if $$(wildcard $$($1_EXITCODE)), \
+ $$(eval $1_EXIT_CODE := $$(shell $$(CAT) $$($1_EXITCODE))) \
+ $$(if $$(filter 0, $$($1_EXIT_CODE)), \
+ $$(eval $1_PASSED := 1) \
+ $$(eval $1_ERROR := 0) \
+ , \
+ $$(eval $1_PASSED := 0) \
+ $$(eval $1_ERROR := 1) \
+ ) \
+ $$(eval $1_FAILED := 0) \
+ $$(eval $1_TOTAL := $$(shell \
+ $$(EXPR) $$($1_PASSED) + $$($1_ERROR))) \
+ , \
+ $$(eval $1_PASSED := 0) \
+ $$(eval $1_FAILED := 0) \
+ $$(eval $1_ERROR := 1) \
+ $$(eval $1_TOTAL := 1) \
+ )
+
+ $1: run-test-$1 parse-test-$1
+
+ TARGETS += $1
+endef
+
+################################################################################
+
### Rules for Jtreg
# Helper function for SetupRunJtregTest. Set a JTREG_* variable from, in order:
@@ -849,6 +996,9 @@
UseGtestTestHandler = \
$(if $(filter gtest:%, $1), true)
+UseMicroTestHandler = \
+ $(if $(filter micro:%, $1), true)
+
UseJtregTestHandler = \
$(if $(filter jtreg:%, $1), true)
@@ -870,6 +1020,11 @@
TEST := $(test), \
)) \
) \
+ $(if $(call UseMicroTestHandler, $(test)), \
+ $(eval $(call SetupRunMicroTest, $(TEST_ID), \
+ TEST := $(test), \
+ )) \
+ ) \
$(if $(call UseJtregTestHandler, $(test)), \
$(eval $(call SetupRunJtregTest, $(TEST_ID), \
TEST := $(test), \
--- a/make/autoconf/configure.ac Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/configure.ac Fri Nov 16 23:39:51 2018 +0100
@@ -180,6 +180,9 @@
# Setup the JTReg Regression Test Harness.
TOOLCHAIN_SETUP_JTREG
+# Setup the Java Microbenchmark Harness (JMH)
+LIB_TESTS_SETUP_JMH
+
# Setup Jib dependency tool
TOOLCHAIN_SETUP_JIB
--- a/make/autoconf/lib-tests.m4 Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/lib-tests.m4 Fri Nov 16 23:39:51 2018 +0100
@@ -55,3 +55,65 @@
AC_SUBST(GRAALUNIT_LIB)
])
+###############################################################################
+#
+# Setup and check the Java Microbenchmark Harness
+#
+AC_DEFUN_ONCE([LIB_TESTS_SETUP_JMH],
+[
+ AC_ARG_WITH(jmh, [AS_HELP_STRING([--with-jmh],
+ [Java Microbenchmark Harness for building the OpenJDK Microbenchmark Suite])])
+
+ AC_MSG_CHECKING([for jmh (Java Microbenchmark Harness)])
+ if test "x$with_jmh" = xno || test "x$with_jmh" = x; then
+ AC_MSG_RESULT([no, disabled])
+ elif test "x$with_jmh" = xyes; then
+ AC_MSG_RESULT([no, error])
+ AC_MSG_ERROR([--with-jmh requires a directory containing all jars needed by JMH])
+ else
+ # Path specified
+ JMH_HOME="$with_jmh"
+ if test ! -d [$JMH_HOME]; then
+ AC_MSG_RESULT([no, error])
+ AC_MSG_ERROR([$JMH_HOME does not exist or is not a directory])
+ fi
+ BASIC_FIXUP_PATH([JMH_HOME])
+
+ jar_names="jmh-core jmh-generator-annprocess jopt-simple commons-math3"
+ for jar in $jar_names; do
+ found_jar_files=$($ECHO $(ls $JMH_HOME/$jar-*.jar 2> /dev/null))
+
+ if test "x$found_jar_files" = x; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([--with-jmh does not contain $jar-*.jar])
+ elif ! test -e "$found_jar_files"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([--with-jmh contain multiple $jar-*.jar: $found_jar_files])
+ fi
+
+ found_jar_var_name=found_${jar//-/_}
+ eval $found_jar_var_name='"'$found_jar_files'"'
+ done
+ AC_MSG_RESULT([yes])
+
+ JMH_CORE_JAR=$found_jmh_core
+ JMH_GENERATOR_JAR=$found_jmh_generator_annprocess
+ JMH_JOPT_SIMPLE_JAR=$found_jopt_simple
+ JMH_COMMONS_MATH_JAR=$found_commons_math3
+
+
+ if [ [[ "$JMH_CORE_JAR" =~ jmh-core-(.*)\.jar$ ]] ] ; then
+ JMH_VERSION=${BASH_REMATCH[[1]]}
+ else
+ JMH_VERSION=unknown
+ fi
+
+ AC_MSG_NOTICE([JMH core version: $JMH_VERSION])
+ fi
+
+ AC_SUBST(JMH_CORE_JAR)
+ AC_SUBST(JMH_GENERATOR_JAR)
+ AC_SUBST(JMH_JOPT_SIMPLE_JAR)
+ AC_SUBST(JMH_COMMONS_MATH_JAR)
+ AC_SUBST(JMH_VERSION)
+])
--- a/make/autoconf/spec.gmk.in Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/spec.gmk.in Fri Nov 16 23:39:51 2018 +0100
@@ -355,6 +355,12 @@
LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@
GRAALUNIT_LIB := @GRAALUNIT_LIB@
+JMH_CORE_JAR := @JMH_CORE_JAR@
+JMH_GENERATOR_JAR := @JMH_GENERATOR_JAR@
+JMH_JOPT_SIMPLE_JAR := @JMH_JOPT_SIMPLE_JAR@
+JMH_COMMONS_MATH_JAR := @JMH_COMMONS_MATH_JAR@
+JMH_VERSION := @JMH_VERSION@
+
# Source file for cacerts
CACERTS_FILE=@CACERTS_FILE@
--- a/make/common/FindTests.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/common/FindTests.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -72,6 +72,9 @@
# Add Gtest
ALL_NAMED_TESTS += gtest
+# Add microbenchmarks
+ALL_NAMED_TESTS += micro
+
# Find make test targets
MAKE_TEST_TARGETS := $(shell $(MAKE) -s --no-print-directory $(MAKE_ARGS) \
SPEC=$(SPEC) -f $(TOPDIR)/test/make/TestMake.gmk print-targets)
--- a/make/common/JarArchive.gmk Fri Nov 16 13:23:50 2018 -0500
+++ b/make/common/JarArchive.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -43,6 +43,7 @@
# For this to work, the source files must exist when the makefile is
# parsed.
# SRCS:=List of directories in where to find files to add to archive
+# BIN:=Directory where to store build control files
# SUFFIXES:=File suffixes to include in jar
# INCLUDES:=List of directories/packages in SRCS that should be included
# EXCLUDES:=List of directories/packages in SRCS that should be excluded
@@ -62,10 +63,11 @@
$1_JARMAIN:=$(strip $$($1_JARMAIN))
$1_JARNAME:=$$(notdir $$($1_JAR))
- $1_MANIFEST_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_manifest
- $1_DELETESS_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_deletess
- $1_DELETES_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_deletes
- $1_BIN:=$$(dir $$($1_JAR))
+ $1_JAR_OUTPUT_DIR := $$(patsubst %/, %, $$(dir $$($1_JAR)))
+ $$(call SetIfEmpty, $1_BIN, $$($1_JAR_OUTPUT_DIR))
+ $1_MANIFEST_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_manifest
+ $1_DELETESS_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_deletess
+ $1_DELETES_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_deletes
$$(call SetIfEmpty, $1_JAR_CMD, $$(JAR))
ifeq (,$$($1_SUFFIXES))
@@ -231,11 +233,12 @@
$1_VARDEPS := $$($1_JAR_CMD) $$($1_JAR_CREATE_OPTIONS) $$($1_MANIFEST) \
$$($1_JARMAIN) $$($1_EXTRA_MANIFEST_ATTR) $$($1_ORIG_DEPS) $$($1_SRCS) \
$$($1_INCLUDES) $$($1_EXCLUDES) $$($1_EXCLUDE_FILES) $$($1_EXTRA_FILES)
- $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$(dir $$($1_JAR))_the.$$($1_JARNAME).vardeps)
+ $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BIN)/_the.$$($1_JARNAME).vardeps)
# Here is the rule that creates/updates the jar file.
$$($1_JAR) : $$($1_DEPENDENCIES) $$($1_MANIFEST) $$($1_VARDEPS_FILE)
$$(call MakeTargetDir)
+ $$(call MakeDir, $$($1_BIN))
$$($1_GREP_INCLUDE_OUTPUT)
$$($1_GREP_EXCLUDE_OUTPUT)
# If the vardeps file is part of the newer prereq list, it means that
--- a/make/conf/jib-profiles.js Fri Nov 16 13:23:50 2018 -0500
+++ b/make/conf/jib-profiles.js Fri Nov 16 23:39:51 2018 +0100
@@ -243,7 +243,7 @@
// These are the base setttings for all the main build profiles.
common.main_profile_base = {
- dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf"],
+ dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf", "jmh"],
default_make_targets: ["product-bundles", "test-bundles"],
configure_args: concat(["--enable-jtreg-failure-handler"],
"--with-exclude-translations=de,es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK",
@@ -892,6 +892,12 @@
environment_path: input.get("jtreg", "install_path") + "/jtreg/bin"
},
+ jmh: {
+ organization: common.organization,
+ ext: "tar.gz",
+ revision: "1.21+1.0"
+ },
+
gnumake: {
organization: common.organization,
ext: "tar.gz",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/devkit/createJMHBundle.sh Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,50 @@
+#!/bin/bash -e
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+# Create a bundle in the build directory, containing what's needed to
+# build and run JMH microbenchmarks from the OpenJDK build.
+
+JMH_VERSION=1.21
+COMMONS_MATH3_VERSION=3.2
+JOPT_SIMPLE_VERSION=4.6
+
+BUNDLE_NAME=jmh-$JMH_VERSION.tar.gz
+
+SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
+BUILD_DIR="${SCRIPT_DIR}/../../build/jmh"
+JAR_DIR="$BUILD_DIR/jars"
+
+mkdir -p $BUILD_DIR $JAR_DIR
+cd $JAR_DIR
+rm -f *
+
+wget http://central.maven.org/maven2/org/apache/commons/commons-math3/$COMMONS_MATH3_VERSION/commons-math3-$COMMONS_MATH3_VERSION.jar
+wget http://central.maven.org/maven2/net/sf/jopt-simple/jopt-simple/$JOPT_SIMPLE_VERSION/jopt-simple-$JOPT_SIMPLE_VERSION.jar
+wget http://central.maven.org/maven2/org/openjdk/jmh/jmh-core/$JMH_VERSION/jmh-core-$JMH_VERSION.jar
+wget http://central.maven.org/maven2/org/openjdk/jmh/jmh-generator-annprocess/$JMH_VERSION/jmh-generator-annprocess-$JMH_VERSION.jar
+
+tar -cvzf ../$BUNDLE_NAME *
+
+echo "Created $BUILD_DIR/$BUNDLE_NAME"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/test/BuildMicrobenchmark.gmk Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+ifeq ($(JMH_CORE_JAR), )
+ $(info Error: JMH is missing. Please use configure --with-jmh.)
+ $(error Cannot continue)
+endif
+
+#### Variables
+
+MICROBENCHMARK_SRC := $(TOPDIR)/test/micro
+MICROBENCHMARK_JAR := $(IMAGES_OUTPUTDIR)/test/micro/benchmarks.jar
+
+MICROBENCHMARK_OUTPUT := $(SUPPORT_OUTPUTDIR)/test/micro
+MICROBENCHMARK_CLASSES := $(MICROBENCHMARK_OUTPUT)/classes
+MICROBENCHMARK_JAR_BIN := $(MICROBENCHMARK_OUTPUT)/jar
+
+JMH_UNPACKED_DIR := $(MICROBENCHMARK_OUTPUT)/jmh_jars
+JMH_UNPACKED_JARS_DONE := $(JMH_UNPACKED_DIR)/_unpacked.marker
+
+# External dependencies
+JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR)
+JMH_RUNTIME_JARS := $(JMH_CORE_JAR) $(JMH_COMMONS_MATH_JAR) $(JMH_JOPT_SIMPLE_JAR)
+
+MICROBENCHMARK_CLASSPATH := $(call PathList, $(JMH_COMPILE_JARS))
+
+###
+
+# Need double \n to get new lines and no trailing spaces
+MICROBENCHMARK_MANIFEST := Build: $(FULL_VERSION)\n\
+\nJMH-Version: $(JMH_VERSION)\n\
+\nName: OpenJDK Microbenchmark Suite
+
+
+#### Compile Targets
+
+# Building microbenchmark requires the jdk.unsupported and java.management modules,
+# and to have sjavac disabled.
+$(eval $(call SetupJavaCompiler, MICROBENCHMARK_JAVA_COMPILER, \
+ JVM := $(JAVA) --add-modules jdk.unsupported --limit-modules java.management, \
+ JAVAC := $(NEW_JAVAC), \
+ DISABLE_SJAVAC := true, \
+ FLAGS := --upgrade-module-path $(JDK_OUTPUTDIR)/modules --system none $(DISABLE_WARNINGS), \
+ SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+ SERVER_JVM := $(SJAVAC_SERVER_JAVA), \
+))
+
+# Build microbenchmark suite for the current JDK
+$(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
+ SETUP := MICROBENCHMARK_JAVA_COMPILER, \
+ ADD_JAVAC_FLAGS := -cp $(MICROBENCHMARK_CLASSPATH) -Xlint -Werror, \
+ SRC := $(MICROBENCHMARK_SRC), \
+ BIN := $(MICROBENCHMARK_CLASSES), \
+))
+
+$(BUILD_JDK_MICROBENCHMARK): $(JMH_COMPILE_JARS)
+
+# Unpacking dependencies for inclusion in the benchmark JARs
+$(JMH_UNPACKED_JARS_DONE): $(JMH_RUNTIME_JARS)
+ $(RM) -r $(JMH_UNPACKED_DIR)
+ $(MKDIR) -p $(JMH_UNPACKED_DIR)
+ $(foreach jar, $(JMH_RUNTIME_JARS), \
+ $$($(UNZIP) -oq $(jar) -d $(JMH_UNPACKED_DIR)))
+ $(RM) -r $(JMH_UNPACKED_DIR)/META-INF
+ $(RM) $(JMH_UNPACKED_DIR)/*.xml
+ $(TOUCH) $@
+
+# Create benchmarks JAR file with benchmarks for both the old and new JDK
+$(eval $(call SetupJarArchive, BUILD_JDK_JAR, \
+ DEPENDENCIES := $(BUILD_JDK_MICROBENCHMARK) $(JMH_UNPACKED_JARS_DONE), \
+ SRCS := $(MICROBENCHMARK_CLASSES) $(JMH_UNPACKED_DIR), \
+ BIN := $(MICROBENCHMARK_JAR_BIN), \
+ SUFFIXES := .*, \
+ EXCLUDE_FILES:= _the.BUILD_JDK_MICROBENCHMARK_batch \
+ _the.BUILD_JDK_MICROBENCHMARK.vardeps _unpacked.marker, \
+ EXTRA_MANIFEST_ATTR := $(MICROBENCHMARK_MANIFEST), \
+ JARMAIN := org.openjdk.jmh.Main, \
+ JAR := $(MICROBENCHMARK_JAR), \
+))
+
+all: $(MICROBENCHMARK_JAR)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/BlackholedOutputStream.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BlackholedOutputStream extends OutputStream {
+
+ private final Blackhole bh;
+
+ public BlackholedOutputStream(Blackhole bh) {
+ this.bh = bh;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ bh.consume(b);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ bh.consume(b);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ bh.consume(b);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileChannelRead.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileChannelRead {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private File f;
+ private FileChannel fc;
+ private ByteBuffer bb;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("FileChannelReadBench", ".bin");
+ try (FileOutputStream fos = new FileOutputStream(f)) {
+ for (int i = 0; i < fileSize; i++) {
+ fos.write((byte) i);
+ }
+ }
+ bb = ByteBuffer.allocate(1);
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws IOException {
+ fc = FileChannel.open(f.toPath(), StandardOpenOption.READ);
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ fc.close();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ int ret = fc.read(bb);
+ bb.flip();
+ if (ret == -1) {
+ // start over
+ fc.position(0);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileChannelWrite.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileChannelWrite {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private File f;
+ private FileChannel fc;
+ private ByteBuffer bb;
+ private int count;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("FileChannelWriteBench", ".bin");
+ bb = ByteBuffer.allocate(1);
+ bb.put((byte) 47);
+ bb.flip();
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws IOException {
+ fc = FileChannel.open(f.toPath(), StandardOpenOption.WRITE);
+ count = 0;
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ fc.close();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ fc.write(bb);
+ bb.flip();
+ count++;
+ if (count >= fileSize) {
+ // start over
+ fc.position(0);
+ count = 0;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileRead.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileRead {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private File f;
+ private FileInputStream fis;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("FileReadBench", ".bin");
+ try (FileOutputStream fos = new FileOutputStream(f)) {
+ for (int i = 0; i < fileSize; i++) {
+ fos.write((byte) i);
+ }
+ }
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws FileNotFoundException {
+ fis = new FileInputStream(f);
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ fis.close();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ int ret = fis.read();
+ if (ret == -1) {
+ // start over
+ fis.close();
+ fis = new FileInputStream(f);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileWrite.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileWrite {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private File f;
+ private FileOutputStream fos;
+ private long count;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("FileWriteBench", ".bin");
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws FileNotFoundException {
+ fos = new FileOutputStream(f);
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ fos.close();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ fos.write((byte) count);
+ count++;
+ if (count >= fileSize) {
+ // restart
+ fos.close();
+ fos = new FileOutputStream(f);
+ count = 0;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/ObjectStreamClasses.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A micro benchmark used to measure the performance impact from multi threaded access to ObjectStreamClass.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ObjectStreamClasses {
+
+ public Class<?>[] classes;
+
+ @Setup
+ public void setup() {
+ LinkedList<Class> queue = new LinkedList<Class>();
+ int i = 0;
+ while (true) {
+ // Loop until we get a ClassNotFoundException
+ // Maybe rewrite this considering the fact that there are 29
+ // inner classes available?
+ try {
+ Class clazz = Class.forName(ObjectStreamClasses.class.getName() + "$SerializableClass" + i++);
+ queue.add(clazz);
+ } catch (ClassNotFoundException e) {
+ break;
+ }
+ }
+ classes = new Class[queue.size()];
+
+ // Make ObjectStreamClass load all classes into the static map
+ i = 0;
+ while (!queue.isEmpty()) {
+ classes[i] = (Class) queue.remove();
+ i++;
+ }
+ }
+
+ /**
+ * Tests the static lookup function. Depending on JRE version the internal behavior is different but the general
+ * behavior is a synchronized call to some sort of static container.
+ */
+ @Benchmark
+ public void testLookup(Blackhole bh) {
+ for (Class<?> klass : classes) {
+ bh.consume(ObjectStreamClass.lookup(klass));
+ }
+ }
+
+ static class SerializableClass0 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass1 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass2 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass3 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass4 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass5 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass6 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass7 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass8 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass9 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass10 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass11 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass12 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass13 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass14 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass15 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass16 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass17 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass18 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass19 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass20 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass21 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass22 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass23 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass24 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass25 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass26 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass27 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass28 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ static class SerializableClass29 extends SerializableClass {
+ private static final long serialVersionUID = 1L;
+ }
+
+ @SuppressWarnings("unused")
+ private static class SerializableClass implements Serializable {
+
+ private static final long serialVersionUID = 6107539118220989250L;
+ public Object objectField00 = new Object();
+ public Object objectField01 = new Object();
+ public Object objectField02 = new Object();
+ public Object objectField03 = new Object();
+ public Object objectField04 = new Object();
+ public Object objectField05 = new Object();
+ public Object objectField06 = new Object();
+ public Object objectField07 = new Object();
+ public Object objectField08 = new Object();
+ public Object objectField09 = new Object();
+ public Object objectField10 = new Object();
+ public Object objectField11 = new Object();
+ public Object objectField12 = new Object();
+ public Object objectField13 = new Object();
+ public Object objectField14 = new Object();
+ public Object objectField15 = new Object();
+ public Object objectField16 = new Object();
+ public Object objectField17 = new Object();
+ public Object objectField18 = new Object();
+ public Object objectField19 = new Object();
+ public Object objectField20 = new Object();
+ public Object objectField21 = new Object();
+ public Object objectField22 = new Object();
+ public Object objectField23 = new Object();
+ public Object objectField24 = new Object();
+ public Object objectField25 = new Object();
+ public Object objectField26 = new Object();
+ public Object objectField27 = new Object();
+ public Object objectField28 = new Object();
+ public Object objectField29 = new Object();
+
+ SerializableClass() {
+ super();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+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.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class RandomAccessRead {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private RandomAccessFile raf;
+ private long offset;
+ private int deltaIndex;
+ private int[] deltas;
+ private File f;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("RandomAccessBench", ".bin");
+ try (FileOutputStream fos = new FileOutputStream(f)) {
+ for (int i = 0; i < fileSize; i++) {
+ fos.write((byte) i);
+ }
+ }
+ deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws IOException {
+ raf = new RandomAccessFile(f, "rw");
+ offset = 0;
+ deltaIndex = 0;
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ raf.close();
+ }
+
+ @Benchmark
+ public int test() throws IOException {
+ offset = offset + deltas[deltaIndex];
+ if (offset >= fileSize) {
+ offset = 0;
+ }
+ deltaIndex++;
+ if (deltaIndex >= deltas.length) {
+ deltaIndex = 0;
+ }
+ raf.seek(offset);
+ return raf.read();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/RandomAccessWrite.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+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.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class RandomAccessWrite {
+
+ @Param("1000000")
+ private int fileSize;
+
+ private File f;
+ private RandomAccessFile raf;
+ private long offset;
+ private int deltaIndex;
+ private int[] deltas;
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ f = File.createTempFile("RandomAccessBench", ".bin");
+ try (FileOutputStream fos = new FileOutputStream(f)) {
+ for (int i = 0; i < fileSize; i++) {
+ fos.write((byte) i);
+ }
+ }
+ deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException {
+ f.delete();
+ }
+
+ @Setup(Level.Iteration)
+ public void beforeIteration() throws IOException {
+ raf = new RandomAccessFile(f, "rw");
+ offset = 0;
+ deltaIndex = 0;
+ }
+
+ @TearDown(Level.Iteration)
+ public void afterIteration() throws IOException {
+ raf.close();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ offset = offset + deltas[deltaIndex];
+ if (offset >= fileSize) {
+ offset = 0;
+ }
+ deltaIndex++;
+ if (deltaIndex >= deltas.length) {
+ deltaIndex = 0;
+ }
+ raf.seek(offset);
+ raf.write((byte) offset);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/SerializationWriteReplace.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.bench.java.io.BlackholedOutputStream;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SerializationWriteReplace {
+
+ private BlackholedOutputStream bos;
+ private ObjectOutputStream os;
+
+ @Setup
+ public void setupStreams(Blackhole bh) throws IOException {
+ bos = new BlackholedOutputStream(bh);
+ os = new ObjectOutputStream(bos);
+ }
+
+ @TearDown
+ public void downStreams() throws IOException {
+ os.close();
+ bos.close();
+ os = null;
+ bos = null;
+ }
+
+ @Benchmark
+ public void writeReplace() throws IOException, ClassNotFoundException {
+ os.writeObject(new Class2());
+ }
+
+ public abstract static class Base implements Serializable {
+ private static final long serialVersionUID = 1L;
+ }
+
+ public static class Class1 extends Base {
+ private static final long serialVersionUID = 2L;
+ }
+
+ public static class Class2 extends Class1 {
+ private static final long serialVersionUID = 3L;
+ Object writeReplace() throws ObjectStreamException {
+ return new Class3();
+ }
+ }
+
+ public static class Class3 extends Base {
+ private static final long serialVersionUID = 4L;
+ private String tuto = "tuto";
+ private byte b = (byte) 0xff;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/UTF8.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring UTF8 char operations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class UTF8 {
+
+ private String s;
+ private BlackholedOutputStream bos;
+ private DataOutputStream dos;
+
+ @Setup
+ public void setup(Blackhole bh) {
+ bos = new BlackholedOutputStream(bh);
+ dos = new DataOutputStream(bos);
+ s = "abcdefghijklmnopqrstuvxyz0123456789";
+ }
+
+ @Benchmark
+ public void testCharConversion() throws IOException {
+ dos.writeUTF(s);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopy.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring System.arraycopy in different ways.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopy {
+
+ private static final byte[] TEST_BYTES = "HTTP/1.0".getBytes();
+ private static final char[] TEST_CHARS = new char[46];
+ private static final Object[] TEST_OBJECTS = new Object[200]; // Uses a minimum of 160 internal positions for internal copying
+
+ // a length which the compiler cannot prove is a constant
+ public static int nonConstCharLength = TEST_CHARS.length;
+ public static int nonConstByteLength = TEST_BYTES.length;
+ public static int nonConstObjectLength = TEST_OBJECTS.length;
+
+ // Use this array to copy objects in.
+ public char[] dummyCharArray = new char[TEST_CHARS.length];
+ public byte[] dummyByteArray = new byte[TEST_BYTES.length];
+ public Object[] dummyObjectArray = new Object[TEST_OBJECTS.length];
+
+ @Setup
+ public void setup() {
+ for (int i = 0; i < TEST_OBJECTS.length; i++) {
+ TEST_OBJECTS[i] = new Object();
+ dummyObjectArray[i] = new Object();
+ }
+ }
+
+ /**
+ * This test case do the same work as testArrayCopy. We should make sure
+ * testArrayCopy is equally fast or better. Compare the two and you measure
+ * the system call versus explicit copy for-loop.
+ */
+ @Benchmark
+ public void copyLoop() {
+ for (int j = 0; j < dummyByteArray.length; j++) {
+ dummyByteArray[j] = TEST_BYTES[j];
+ }
+ }
+
+ /**
+ * Test that we can optimize away the code since it should not have any side
+ * effects
+ */
+ @Benchmark
+ public void copyLoopLocalArray() {
+ byte[] localDummyByteArray = new byte[TEST_BYTES.length];
+ for (int j = 0; j < localDummyByteArray.length; j++) {
+ localDummyByteArray[j] = TEST_BYTES[j];
+ }
+ }
+
+ /**
+ * This test case do the same work as testArrayCopy. We should make sure
+ * testArrayCopy is equally fast or better. Compare the two and you measure
+ * the system call versus explicit copy for-loop.
+ * <p/>
+ * Uses non-provable constant length.
+ */
+ @Benchmark
+ public void copyLoopNonConst() {
+ for (int i = 0; i < nonConstByteLength; i++) {
+ dummyByteArray[i] = TEST_BYTES[i];
+ }
+ }
+
+ /**
+ * This test case do the same work as testCopyLoop. We should make sure
+ * testArrayCopy is equally fast or better. Compare the two and you measure
+ * the system call versus explicit copy for-loop.
+ */
+ @Benchmark
+ public void arrayCopy() {
+ System.arraycopy(TEST_BYTES, 0, dummyByteArray, 0, dummyByteArray.length);
+ }
+
+ /**
+ * Test that we can optimize away the code since it should not have any side
+ * effects
+ */
+ @Benchmark
+ public void arrayCopyLocalArray() {
+ byte[] localDummyByteArray = new byte[TEST_BYTES.length];
+ System.arraycopy(TEST_BYTES, 0, localDummyByteArray, 0, localDummyByteArray.length);
+ }
+
+ /**
+ * This test case do the same work as testCopyLoop. We should make sure
+ * testArrayCopy is equally fast or better. Compare the two and you measure
+ * the system call versus explicit copy for-loop.
+ * <p/>
+ * Uses non-provable constant length.
+ */
+ @Benchmark
+ public void arrayCopyNonConst() {
+ System.arraycopy(TEST_BYTES, 0, dummyByteArray, 0, nonConstByteLength);
+ }
+
+ @Benchmark
+ public void arrayCopyChar() {
+ System.arraycopy(TEST_CHARS, 0, dummyCharArray, 0, dummyCharArray.length);
+ }
+
+ @Benchmark
+ public void arrayCopyCharNonConst() {
+ System.arraycopy(TEST_CHARS, 0, dummyCharArray, 0, nonConstCharLength);
+ }
+
+ @Benchmark
+ public void arrayCopyObject() {
+ System.arraycopy(TEST_OBJECTS, 0, dummyObjectArray, 0, dummyObjectArray.length);
+ }
+
+ @Benchmark
+ public void arrayCopyObjectNonConst() {
+ System.arraycopy(TEST_OBJECTS, 0, dummyObjectArray, 0, nonConstObjectLength);
+ }
+
+ /**
+ * This test copies inside a object array, that is same source array as dest
+ * array. Copies backwards in the array.
+ */
+ @Benchmark
+ @OperationsPerInvocation(40)
+ public void arrayCopyObjectSameArraysBackward() {
+ for (int i = 0; i < 40; i++) {
+ System.arraycopy(dummyObjectArray, i, dummyObjectArray, i + 40, 80);
+ }
+ }
+
+ /**
+ * This test copies inside a object array, that is same source array as dest
+ * array. Copies forward in the array. There is a special version for this
+ * in JRockit.
+ */
+ @Benchmark
+ @OperationsPerInvocation(40)
+ public void arrayCopyObjectSameArraysForward() {
+ for (int i = 0; i < 40; i++) {
+ System.arraycopy(dummyObjectArray, i + 40, dummyObjectArray, i, 80);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyAligned.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring aligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyAligned {
+
+ @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+ int length;
+
+ int fromPos, toPos;
+ byte[] fromByteArr, toByteArr;
+ char[] fromCharArr, toCharArr;
+ int[] fromIntArr, toIntArr;
+ long[] fromLongArr, toLongArr;
+
+ @Setup
+ public void setup() {
+ // Both positions aligned
+ fromPos = 8;
+ toPos = 8;
+
+ fromByteArr = new byte[1210];
+ toByteArr = new byte[1210];
+ fromCharArr = new char[1210];
+ toCharArr = new char[1210];
+ fromIntArr = new int[1210];
+ toIntArr = new int[1210];
+ fromLongArr = new long[1210];
+ toLongArr = new long[1210];
+ }
+
+ @Benchmark
+ public void testByte() {
+ System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testChar() {
+ System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testInt() {
+ System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testLong() {
+ System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedBoth.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedBoth {
+
+ @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+ int length;
+
+ int fromPos, toPos;
+ byte[] fromByteArr, toByteArr;
+ char[] fromCharArr, toCharArr;
+ int[] fromIntArr, toIntArr;
+ long[] fromLongArr, toLongArr;
+
+ @Setup
+ public void setup() {
+ // Both positions Unaligned
+ fromPos = 9;
+ toPos = 10;
+
+ fromByteArr = new byte[1210];
+ toByteArr = new byte[1210];
+ fromCharArr = new char[1210];
+ toCharArr = new char[1210];
+ fromIntArr = new int[1210];
+ toIntArr = new int[1210];
+ fromLongArr = new long[1210];
+ toLongArr = new long[1210];
+ }
+
+ @Benchmark
+ public void testByte() {
+ System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testChar() {
+ System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testInt() {
+ System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testLong() {
+ System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedDst.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedDst {
+
+ @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+ int length;
+
+ int fromPos, toPos;
+ byte[] fromByteArr, toByteArr;
+ char[] fromCharArr, toCharArr;
+ int[] fromIntArr, toIntArr;
+ long[] fromLongArr, toLongArr;
+
+ @Setup
+ public void setup() {
+ // Dst position Unaligned
+ fromPos = 8;
+ toPos = 9;
+
+ fromByteArr = new byte[1210];
+ toByteArr = new byte[1210];
+ fromCharArr = new char[1210];
+ toCharArr = new char[1210];
+ fromIntArr = new int[1210];
+ toIntArr = new int[1210];
+ fromLongArr = new long[1210];
+ toLongArr = new long[1210];
+ }
+
+ @Benchmark
+ public void testByte() {
+ System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testChar() {
+ System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testInt() {
+ System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testLong() {
+ System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedSrc.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedSrc {
+
+ @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+ int length;
+
+ int fromPos, toPos;
+ byte[] fromByteArr, toByteArr;
+ char[] fromCharArr, toCharArr;
+ int[] fromIntArr, toIntArr;
+ long[] fromLongArr, toLongArr;
+
+ @Setup
+ public void setup() {
+ // Dst position Unaligned
+ fromPos = 5;
+ toPos = 8;
+
+ fromByteArr = new byte[1210];
+ toByteArr = new byte[1210];
+ fromCharArr = new char[1210];
+ toCharArr = new char[1210];
+ fromIntArr = new int[1210];
+ toIntArr = new int[1210];
+ fromLongArr = new long[1210];
+ toLongArr = new long[1210];
+ }
+
+ @Benchmark
+ public void testByte() {
+ System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testChar() {
+ System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testInt() {
+ System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+ }
+
+ @Benchmark
+ public void testLong() {
+ System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ClassForName.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.lang.Class.forName() with various inputs.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ClassForName {
+
+ private String aName, bName, cName;
+
+ @Setup
+ public void setup() {
+ aName = A.class.getName();
+ bName = B.class.getName();
+ cName = C.class.getName();
+ }
+
+ /** Calls Class.forName with the same name over and over again. The class asked for exists. */
+ @Benchmark
+ public void test1(Blackhole bh) throws ClassNotFoundException {
+ bh.consume(Class.forName(aName));
+ }
+
+ /** Calls Class.forName with the three different names over and over again. All classes asked for exist. */
+ @Benchmark
+ public void test3(Blackhole bh) throws ClassNotFoundException {
+ bh.consume(Class.forName(aName));
+ bh.consume(Class.forName(bName));
+ bh.consume(Class.forName(cName));
+ }
+
+ static class A {}
+ static class B {}
+ static class C {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Clone.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.BitSet;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Clone {
+
+ private BitSet testObj1;
+ private Date testObj2;
+ private char[] testObj3;
+
+ @Setup
+ public void setup() {
+ testObj1 = new BitSet(10);
+ testObj2 = new Date();
+ testObj3 = new char[5];
+ }
+
+ /** Calls clone on three different types. The types are java.util.BitSet, java.util.Date and char[]. */
+ @Benchmark
+ public void cloneThreeDifferent(Blackhole bh) {
+ bh.consume(testObj1.clone());
+ bh.consume(testObj2.clone());
+ bh.consume(testObj3.clone());
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/FloatingDecimal.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for sun.misc.FloatingDecimal. Performs floating point number to String conversions.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class FloatingDecimal {
+
+ private double[] randomArray, twoDecimalsArray, integerArray;
+ private static final int TESTSIZE = 1000;
+
+ @Setup
+ public void setup() {
+ Random r = new Random(1123);
+ randomArray = new double[TESTSIZE];
+ twoDecimalsArray = new double[TESTSIZE];
+ integerArray = new double[TESTSIZE];
+ for (int i = 0; i < TESTSIZE; i++) {
+ randomArray[i] = r.nextDouble() * 10000.0D;
+ twoDecimalsArray[i] = ((double) (10000 - r.nextInt(20000))) / 100;
+ integerArray[i] = (double) (100 - r.nextInt(200));
+ }
+ }
+
+ /** Tests Double.toString on double values generated from Random.nextDouble() */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void randomDoubleToString(Blackhole bh) {
+ for (double d : randomArray) {
+ bh.consume(Double.toString(d));
+ }
+ }
+
+ /** Tests Double.toString on double values that are integers between -100 and 100. */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void integerDoubleToString(Blackhole bh) {
+ for (double d : integerArray) {
+ bh.consume(Double.toString(d));
+ }
+ }
+
+ /** Tests Double.toString on double values that are between -100 and 100 and have two decimal digits. */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void twoDecimalsDoubleToString(Blackhole bh) {
+ for (double d : twoDecimalsArray) {
+ bh.consume(Double.toString(d));
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/GetStackTrace.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests Thread.getStackTrace()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class GetStackTrace {
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public StackTraceElement[] depth0() {
+ return Thread.currentThread().getStackTrace();
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public StackTraceElement[] depth1() {
+ return depth0();
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public StackTraceElement[] depth2() {
+ return depth1();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Integers.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.lang.Integer
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Integers {
+
+ @Param("500")
+ private int size;
+
+ private String[] strings;
+
+ @Setup
+ public void setup() {
+ Random r = new Random(0);
+ strings = new String[size];
+ for (int i = 0; i < size; i++) {
+ strings[i] = "" + (r.nextInt(10000) - 5000);
+ }
+ }
+
+ @Benchmark
+ public void parseInt(Blackhole bh) {
+ for (String s : strings) {
+ bh.consume(Integer.parseInt(s));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Longs.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Longs {
+
+ @Param("500")
+ private int size;
+
+ private long[] longArraySmall;
+ private long[] longArrayBig;
+
+ @Setup
+ public void setup() {
+ longArraySmall = new long[size];
+ longArrayBig = new long[size];
+ for (int i = 0; i < size; i++) {
+ longArraySmall[i] = 100L * i + i + 103L;
+ longArrayBig[i] = ((100L * i + i) << 32) + 4543 + i * 4;
+ }
+ }
+
+ /** Performs toString on a bunch of java.lang.Long:s, all with small values, just a couple of digits. */
+ @Benchmark
+ @Threads(Threads.MAX)
+ public void toStringSmall(Blackhole bh) {
+ for (long value : longArraySmall) {
+ bh.consume(Long.toString(value));
+ }
+ }
+
+ /** Performs toString on a bunch of java.lang.Long:s, all with large values, around 10 digits. */
+ @Benchmark
+ @Threads(Threads.MAX)
+ public void toStringBig(Blackhole bh) {
+ for (long value : longArrayBig) {
+ bh.consume(Long.toString(value));
+ }
+ }
+
+ /*
+ * Have them public to avoid total unrolling
+ */
+ public int innerLoops = 1500;
+
+ @Benchmark
+ @Threads(Threads.MAX)
+ public long repetitiveSubtraction() {
+ long x = 127, dx = 0;
+
+ for (int i = 0; i < innerLoops; i++) {
+ x -= dx;
+ dx = (dx - x);
+ }
+ return x;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/NewInstance.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring java.lang.Class.newInstance speed.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class NewInstance {
+
+ public Class<?>[] samePublicClasses;
+ public Class<?>[] differentPublicClasses;
+ public Class<?>[] differentPublicClassesConstant;
+ public Class<?>[] sameProtectedClasses;
+ public Class<?>[] differentProtectedClasses;
+
+ @Setup
+ public void setup() {
+ samePublicClasses = new Class<?>[]{Apub.class, Apub.class, Apub.class};
+ differentPublicClasses = new Class<?>[]{Apub.class, Bpub.class, Cpub.class};
+ differentPublicClassesConstant = new Class<?>[]{Apub.class, Bpub.class, Cpub.class};
+ sameProtectedClasses = new Class<?>[]{Apro.class, Apro.class, Apro.class};
+ differentProtectedClasses = new Class<?>[]{Apro.class, Bpro.class, Cpro.class};
+ }
+
+ /**
+ * Performs Class.newInstance on the same class over and over again. That it is the same class is not provable at
+ * compile time. The class is protected.
+ */
+ @Benchmark
+ public void threeSameProtected(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ for (Class<?> cl : sameProtectedClasses) {
+ bh.consume(cl.newInstance());
+ }
+ }
+
+ /**
+ * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+ * classes are all protected.
+ */
+ @Benchmark
+ public void threeDifferentProtected(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ for (Class<?> cl : differentProtectedClasses) {
+ bh.consume(cl.newInstance());
+ }
+ }
+
+ /**
+ * Performs Class.newInstance on the same class over and over again. That it is the same class is not provable at
+ * compile time. The class is public.
+ */
+ @Benchmark
+ public void threeSamePublic(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ for (Class<?> cl : samePublicClasses) {
+ bh.consume(cl.newInstance());
+ }
+ }
+
+ /**
+ * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+ * classes are all public.
+ */
+ @Benchmark
+ public void threeDifferentPublic(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ for (Class<?> cl : differentPublicClasses) {
+ bh.consume(cl.newInstance());
+ }
+ }
+
+ /**
+ * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+ * classes are all public.
+ */
+ @Benchmark
+ public void threeDifferentPublicConstant(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ bh.consume(Apub.class.newInstance());
+ bh.consume(Bpub.class.newInstance());
+ bh.consume(Cpub.class.newInstance());
+ }
+
+ @Benchmark
+ public void threeDifferentPublicFinal(Blackhole bh) throws IllegalAccessException, InstantiationException {
+ for (Class<?> cl : differentPublicClassesConstant) {
+ bh.consume(cl.newInstance());
+ }
+ }
+
+ /* Protected test classes */
+ static class Apro {}
+ static class Bpro {}
+ static class Cpro {}
+
+ /* Public test classes */
+ public static class Apub {}
+ public static class Bpub {}
+ public static class Cpub {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ObjectHashCode.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark assesses different hashCode strategies in HotSpot
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ObjectHashCode {
+
+ @Benchmark
+ @Fork
+ public int mode_default() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=0"})
+ public int mode_0() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=1"})
+ public int mode_1() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=2"})
+ public int mode_2() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=3"})
+ public int mode_3() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=4"})
+ public int mode_4() {
+ return System.identityHashCode(new Object());
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=5"})
+ public int mode_5() {
+ return System.identityHashCode(new Object());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringBuffers.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringBuffers {
+
+ private String name;
+ private String blaha;
+ private Sigurd sig;
+
+ @Setup
+ public void setup() {
+ name = "joe";
+ blaha = "sniglogigloienlitenapasomarengrodasjukadjavelhej";
+ sig = new Sigurd();
+ }
+
+ @Benchmark
+ public String appendAndToString() {
+ return "MyStringBuffer named:" + ((name == null) ? "unknown" : name) + ".";
+ }
+
+ @Benchmark
+ public String toStringComplex() {
+ return sig.toString();
+ }
+
+ static class Sigurd {
+ int x;
+ byte y;
+ String z = "yahoo";
+
+ @Override
+ public String toString() {
+ return Integer.toString(x) + "_" + Integer.toString((int) y) + "_" + z + "_";
+ }
+ }
+
+ @Benchmark
+ public String substring() {
+ return blaha.substring(30, 35);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringBuilders {
+
+ private String[] strings;
+ private String[] str3p4p2;
+ private String[] str16p8p7;
+ private String[] str3p9p8;
+ private String[] str22p40p31;
+
+ @Setup
+ public void setup() {
+ strings = new String[]{"As", "your", "attorney,", "I",
+ "advise", "you", "to", "drive", "at", "top", "speed", "it'll",
+ "be", "a", "god", "damn", "miracle", "if", "we", "can", "get",
+ "there", "before", "you", "turn", "into", "a", "wild", "animal."};
+ str3p4p2 = new String[]{"123", "1234", "12"};
+ str16p8p7 = new String[]{"1234567890123456", "12345678", "1234567"};
+ str3p9p8 = new String[]{"123", "123456789", "12345678"};
+ str22p40p31 = new String[]{"1234567890123456789012", "1234567890123456789012345678901234567890", "1234567890123456789012345678901"};
+ }
+
+ /** StringBuilder wins over StringMaker. */
+ @Benchmark
+ public String concat3p4p2() throws Exception {
+ return new StringBuilder(String.valueOf(str3p4p2[0])).append(str3p4p2[1]).append(str3p4p2[2]).toString();
+ }
+
+ /** StringBuilder wins over StringMaker. */
+ @Benchmark
+ public String concat16p8p7() throws Exception {
+ return new StringBuilder(String.valueOf(str16p8p7[0])).append(str16p8p7[1]).append(str16p8p7[2]).toString();
+ }
+
+ /** StringMaker wins over StringBuilder since the two last strings causes StringBuilder to do expand. */
+ @Benchmark
+ public String concat3p9p8() throws Exception {
+ return new StringBuilder(String.valueOf(str3p9p8[0])).append(str3p9p8[1]).append(str3p9p8[2]).toString();
+ }
+
+ /** StringMaker wins over StringBuilder. */
+ @Benchmark
+ public String concat22p40p31() throws Exception {
+ return new StringBuilder(String.valueOf(str22p40p31[0])).append(str22p40p31[1]).append(str22p40p31[2]).toString();
+ }
+
+ @Benchmark
+ public StringBuilder appendLoop8() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 8; i++) {
+ sb.append(strings[i]);
+ }
+ return sb;
+ }
+
+ @Benchmark
+ public StringBuilder appendLoop16() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 16; i++) {
+ sb.append(strings[i]);
+ }
+ return sb;
+ }
+
+ @Benchmark
+ public String toStringCharWithChar1() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ return result.toString();
+ }
+
+ @Benchmark
+ public String toStringCharWithChar2() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ result.append('p');
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithChar4() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ result.append('p');
+ result.append('a');
+ result.append(' ');
+ return result.toString();
+ }
+
+ @Benchmark
+ public String toStringCharWithChar8() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ result.append('p');
+ result.append('a');
+ result.append(' ');
+ result.append('a');
+ result.append('p');
+ result.append('a');
+ result.append(' ');
+ return result.toString();
+ }
+
+ @Benchmark
+ public String toStringCharWithChar16() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ result.append('b');
+ result.append('c');
+ result.append('d');
+ result.append('e');
+ result.append('f');
+ result.append('g');
+ result.append('h');
+ result.append('i');
+ result.append('j');
+ result.append('k');
+ result.append('l');
+ result.append('m');
+ result.append('n');
+ result.append('o');
+ result.append('p');
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithString8() {
+ StringBuilder result = new StringBuilder();
+ result.append("a");
+ result.append("b");
+ result.append("c");
+ result.append("d");
+ result.append("e");
+ result.append("f");
+ result.append("g");
+ result.append("h");
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithString16() {
+ StringBuilder result = new StringBuilder();
+ result.append("a");
+ result.append("b");
+ result.append("c");
+ result.append("d");
+ result.append("e");
+ result.append("f");
+ result.append("g");
+ result.append("h");
+ result.append("i");
+ result.append("j");
+ result.append("k");
+ result.append("l");
+ result.append("m");
+ result.append("n");
+ result.append("o");
+ result.append("p");
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithInt8() {
+ StringBuilder result = new StringBuilder();
+ result.append(2048);
+ result.append(31337);
+ result.append(0xbeefcace);
+ result.append(9000);
+ result.append(4711);
+ result.append(1337);
+ result.append(2100);
+ result.append(2600);
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithBool8() {
+ StringBuilder result = new StringBuilder();
+ result.append(true);
+ result.append(false);
+ result.append(true);
+ result.append(true);
+ result.append(false);
+ result.append(true);
+ result.append(false);
+ result.append(false);
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithFloat8() {
+ StringBuilder result = new StringBuilder();
+ result.append(113.110F);
+ result.append(156456.36435637F);
+ result.append(65436434.64632F);
+ result.append(42654634.64540F);
+ result.append(63464351.64537F);
+ result.append(634564.645711F);
+ result.append(64547.64311F);
+ result.append(4763456341.64531F);
+ return result.toString();
+ }
+
+
+ @Benchmark
+ public String toStringCharWithMixed8() {
+ StringBuilder result = new StringBuilder();
+ result.append('a');
+ result.append("stringelinglinglinglong");
+ result.append('a');
+ result.append("stringelinglinglinglong");
+ result.append('a');
+ result.append("stringelinglinglinglong");
+ result.append('p');
+ result.append("stringelinglinglinglong");
+ return result.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringConcat.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Trivial String concatenation benchmark.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringConcat {
+
+ public int intValue = 4711;
+
+ public String stringValue = String.valueOf(intValue);
+
+ public Object objectValue = Long.valueOf(intValue);
+
+ public boolean boolValue = true;
+
+ public byte byteValue = (byte)-128;
+
+ @Benchmark
+ public String concatConstInt() {
+ return "string" + intValue;
+ }
+
+ @Benchmark
+ public String concatConstString() {
+ return "string" + stringValue;
+ }
+
+ @Benchmark
+ public String concatConstIntConstInt() {
+ return "string" + intValue + "string" + intValue;
+ }
+
+ @Benchmark
+ public String concatConstStringConstInt() {
+ return "string" + stringValue + "string" + intValue;
+ }
+
+ @Benchmark
+ public String concatConst4String() {
+ return "string" + stringValue + stringValue + stringValue + stringValue;
+ }
+
+ @Benchmark
+ public String concatConst2String() {
+ return "string" + stringValue + stringValue;
+ }
+
+ @Benchmark
+ public String concatConstBoolByte() {
+ return "string" + boolValue + byteValue;
+ }
+
+ @Benchmark
+ public String concatConst6String() {
+ return "string" + stringValue + stringValue + stringValue + stringValue + stringValue + stringValue;
+ }
+
+ @Benchmark
+ public String concatConst6Object() {
+ return "string" + objectValue + objectValue + objectValue + objectValue + objectValue + objectValue;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringHashCode.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Performance test of String.hashCode() function
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringHashCode {
+
+ private String hashcode;
+ private String hashcode0;
+
+ @Setup
+ public void setup() {
+ hashcode = "abcdefghijkl";
+ hashcode0 = new String(new char[]{72, 90, 100, 89, 105, 2, 72, 90, 100, 89, 105, 2});
+ }
+
+ /**
+ * Benchmark testing String.hashCode() with a regular 12 char string with
+ * the result possibly cached in String
+ */
+ @Benchmark
+ public int cached() {
+ return hashcode.hashCode();
+ }
+
+ /**
+ * Benchmark testing String.hashCode() with a 12 char string with the
+ * hashcode = 0 forcing the value to always be recalculated.
+ */
+ @Benchmark
+ public int notCached() {
+ return hashcode0.hashCode();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringHttp.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringHttp {
+
+ private byte[] httpRequest;
+ private String[] httpResponse;
+ private byte[] buf;
+
+ @Setup
+ public void setup() {
+ buf = new byte[4080];
+ httpRequest = "GET /foo/bar/baz HTTP/1.1\nHost: foo.com\n".getBytes();
+ httpResponse = new String[]{"Date: 4/20/2003 10:21:31", "Last-Modified: 4/15/2003 10:21:31",
+ "Content-Length: 1234", "", "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+ "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+ "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+ "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+ "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz"};
+ }
+
+ @Benchmark
+ public void parseRequest(Blackhole bh) {
+ bh.consume(new String(httpRequest, 0, 3));
+ bh.consume(new String(httpRequest, 5, 11));
+ bh.consume(new String(httpRequest, 17, 8));
+ bh.consume(new String(httpRequest, 32, 7));
+ }
+
+ @Benchmark
+ public int bufferResponse() {
+ int pos = 0;
+ int n = httpResponse.length;
+
+ for (String s : httpResponse) {
+ byte[] b = s.getBytes();
+ int len = b.length;
+
+ System.arraycopy(b, 0, buf, pos, len);
+ pos += len;
+ buf[pos++] = '\n';
+ }
+ return n;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringIndexOf {
+
+ private String dataString;
+ private String searchString;
+ private String dataStringBig;
+ private String searchStringBig;
+ private String data;
+ private String sub;
+ private String shortSub1;
+ private String data2;
+ private String shortSub2;
+
+ @Setup
+ public void setup() {
+ dataString = "ngdfilsoscargfdgf";
+ searchString = "oscar";
+ dataStringBig = "2937489745890797905764956790452976742965790437698498409583479067ngdcapaapapapasdkajdlkajskldjaslkjdlkasjdsalkjas";
+ searchStringBig = "capaapapapasdkajdlkajskldjaslkjdlkasjdsalk";
+ data = "0000100101010010110101010010101110101001110110101010010101010010000010111010101010101010100010010101110111010101101010100010010100001010111111100001010101001010100001010101001010101010111010010101010101010101010101010";
+ sub = "10101010";
+ shortSub1 = "1";
+ data2 = "00001001010100a10110101010010101110101001110110101010010101010010000010111010101010101010a100010010101110111010101101010100010010a100a0010101111111000010101010010101000010101010010101010101110a10010101010101010101010101010";
+ shortSub2 = "a";
+ }
+
+ /** IndexOf Micros Strings */
+
+ /**
+ * Benchmarks String.indexOf with a rather small String to search and a rather small String to search for. The
+ * searched string contains the string that is searched for.
+ */
+ @Benchmark
+ public int success() {
+ return dataString.indexOf(searchString, 2);
+ }
+
+ /**
+ * Benchmarks String.indexOf with a rather big String to search and a rather big String to search for. The searched
+ * string contains the string that is searched for.
+ */
+ @Benchmark
+ public int successBig() {
+ return dataStringBig.indexOf(searchStringBig, 2);
+ }
+
+ /**
+ * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 8 chars and most
+ * oftenly will require a inner lopp match in String.indexOf with sse42.
+ */
+ @Benchmark
+ public int advancedWithMediumSub() {
+ int index = 0;
+ int dummy = 0;
+ while ((index = data.indexOf(sub, index)) > -1) {
+ index++;
+ dummy += index;
+ }
+ return dummy;
+ }
+
+
+ /**
+ * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 1 chars will find a
+ * huge amount of matches
+ */
+ @Benchmark
+ public int advancedWithShortSub1() {
+ int dummy = 0;
+ int index = 0;
+ while ((index = data.indexOf(shortSub1, index)) > -1) {
+ index++;
+ dummy += index;
+ }
+ return dummy;
+ }
+
+
+ /**
+ * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 1 chars but only with
+ * a few matches.
+ */
+ @Benchmark
+ public int advancedWithShortSub2() {
+ int dummy = 0;
+ int index = 0;
+ while ((index = data2.indexOf(shortSub2, index)) > -1) {
+ index++;
+ dummy += index;
+ }
+ return dummy;
+ }
+
+ @Benchmark
+ public void constantPattern() {
+ String tmp = "simple-hash:SHA-1/UTF-8";
+ if (!tmp.contains("SHA-1")) {
+ throw new RuntimeException("indexOf failed");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringOther.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringOther {
+
+ private String testString;
+ private Random rnd;
+
+ private String str1, str2, str3, str4;
+
+ @Setup
+ public void setup() {
+ testString = "Idealism is what precedes experience; cynicism is what follows.";
+ str1 = "vm-guld vm-guld vm-guld";
+ str2 = "vm-guld vm-guld vm-guldx";
+ str3 = "vm-guld vm-guld vm-guldx";
+ str4 = "adadaskasdjierudks";
+ rnd = new Random();
+ }
+
+ @Benchmark
+ public void charAt(Blackhole bh) {
+ for (int i = 0; i < testString.length(); i++) {
+ bh.consume(testString.charAt(i));
+ }
+ }
+
+ @Benchmark
+ public int compareTo() {
+ int total = 0;
+ total += str1.compareTo(str2);
+ total += str2.compareTo(str3);
+ total += str3.compareTo(str4);
+ return total;
+ }
+
+ /**
+ * Creates (hopefully) unique Strings and internizes them, creating a zillion forgettable strings in the JVMs string
+ * pool.
+ * <p/>
+ * This will test 1.) The data structure/whatever for getting and adding Strings to intern table. 2.) The
+ * intern-caches (java) behaviour on negative lookup (the string is new) 3.) GC's handling of weak handles. Since
+ * every gc we must process and pretty much kill a zillion interned strings that are now not referenced anymore, the
+ * majority of GC time will be spent in handle processing. So we get a picture of how well the pathological case of
+ * this goes.
+ */
+ @Benchmark
+ public String internUnique() {
+ return String.valueOf(rnd.nextInt()).intern();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringUpperLower.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringUpperLower {
+
+ private String strLowerCase;
+ private String strMixedCase;
+ private String strUpperCase;
+
+ @Setup
+ public void setup() {
+ strLowerCase = "this is a simple string with different cases";
+ strMixedCase = "This IS a SImpLE strING wITh DiFfErEnT CASeS";
+ strUpperCase = "THIS IS A SIMPLE STRING WITH DIFFERENT CASES";
+ }
+
+ @Benchmark
+ public String lowerToLower() {
+ return strLowerCase.toLowerCase();
+ }
+
+ @Benchmark
+ public String mixedToLower() {
+ return strMixedCase.toLowerCase();
+ }
+
+ @Benchmark
+ public String upperToLower() {
+ return strUpperCase.toLowerCase();
+ }
+
+ @Benchmark
+ public String lowerToUpper() {
+ return strLowerCase.toUpperCase();
+ }
+
+ @Benchmark
+ public String mixedToUpper() {
+ return strMixedCase.toUpperCase();
+ }
+
+ @Benchmark
+ public String upperToUpper() {
+ return strUpperCase.toUpperCase();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Systems.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Systems {
+
+ @Benchmark
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ @Benchmark
+ public long nanoTime() {
+ return System.nanoTime();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ThreadStartJoin.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Test to launch and gather threads. Measure time for different parts.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+public class ThreadStartJoin {
+
+ private static final int THREADS = Runtime.getRuntime().availableProcessors();
+
+ private Thread[] ts;
+
+ @Benchmark
+ public void test() throws InterruptedException {
+ ts = new TestThread[THREADS];
+
+ for (int i = 0; i < THREADS; i++) {
+ ts[i] = new TestThread();
+ }
+
+ for (int i = 0; i < THREADS; i++) {
+ ts[i].start();
+ }
+
+ for (Thread mythread : ts) {
+ mythread.join();
+
+ if (mythread.isAlive()) {
+ throw new IllegalStateException("Couldn't join in time in LPHhello.");
+ }
+ }
+ }
+
+ @TearDown
+ public final void cleanup() {
+ if (ts != null) {
+ for (Thread t : ts) {
+ if (t != null) {
+ t.interrupt();
+ }
+ }
+ ts = null;
+ }
+ }
+
+ static final class TestThread extends Thread {
+ private static int num = 0;
+
+ public TestThread() {
+ super(TestThread.name());
+ }
+
+ private synchronized static String name() {
+ return "TestThread-" + num++;
+ }
+
+ public void run() {
+ // do nothing
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTarget.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This benchmark evaluates INDY performance under dynamic target updates.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteSetTarget {
+
+ /*
+ * Implementation notes:
+ * - This test makes sense for mutable and volatile call sites only
+ * - Multiple threads are calling the same callsite, and invalidator thread tries to swap target on the fly.
+ * - Additional baseline includes "raw" test, calling callsite's MH directly
+ */
+
+ private static volatile CallSite cs;
+
+ private static MethodHandle doCall1;
+ private static MethodHandle doCall2;
+
+ static {
+ try {
+ doCall1 = MethodHandles.lookup().findVirtual(CallSiteSetTarget.class, "call1", MethodType.methodType(int.class));
+ doCall2 = MethodHandles.lookup().findVirtual(CallSiteSetTarget.class, "call2", MethodType.methodType(int.class));
+ cs = new MutableCallSite(doCall1);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private int i1;
+ private int i2;
+
+ public int call1() {
+ return i1++;
+ }
+
+ public int call2() {
+ return i2++;
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return (int) cs.getTarget().invokeExact(this);
+ }
+
+ @Benchmark
+ public int testMutable() throws Throwable {
+ return (int) INDY_Mutable().invokeExact(this);
+ }
+
+ @Benchmark
+ public int testVolatile() throws Throwable {
+ return (int) INDY_Volatile().invokeExact(this);
+ }
+
+ /* =========================== INDY TRAMPOLINES ============================== */
+
+ private static MethodType MT_bsm() {
+ shouldNotCallThis();
+ return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+ }
+
+ private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+ }
+
+ private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+ }
+
+ private static MethodHandle INDY_Mutable() throws Throwable {
+ shouldNotCallThis();
+ return ((CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTarget.class))).dynamicInvoker();
+ }
+
+ private static MethodHandle INDY_Volatile() throws Throwable {
+ shouldNotCallThis();
+ return ((CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTarget.class))).dynamicInvoker();
+ }
+
+ public static CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteSetTarget.class) {
+ if (cs == null)
+ cs = new MutableCallSite(doCall1);
+ return cs;
+ }
+ }
+
+ public static CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteSetTarget.class) {
+ if (cs == null)
+ cs = new VolatileCallSite(doCall1);
+ return cs;
+ }
+ }
+
+ private static void shouldNotCallThis() {
+ // if this gets called, the transformation has not taken place
+ throw new AssertionError("this code should be statically transformed away by Indify");
+ }
+
+ /* =========================== INVALIDATE LOGIC ============================== */
+
+ private final static Invalidator invalidator = new Invalidator();
+
+ @Setup
+ public void setup() {
+ invalidator.start();
+ }
+
+ @TearDown
+ public void tearDown() throws InterruptedException {
+ invalidator.stop();
+ }
+
+ public static class Invalidator implements Runnable {
+
+ private final long period = Integer.getInteger("period", 1000);
+
+ private final AtomicBoolean started = new AtomicBoolean();
+ private volatile Thread thread;
+
+ @Override
+ public void run() {
+ try {
+ while(!Thread.interrupted()) {
+ if (cs != null) {
+ cs.setTarget(doCall1);
+ }
+ TimeUnit.MICROSECONDS.sleep(period);
+
+ if (cs != null) {
+ cs.setTarget(doCall2);
+ }
+ TimeUnit.MICROSECONDS.sleep(period);
+ }
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+
+ public void start() {
+ if (started.compareAndSet(false, true)) {
+ thread = new Thread(this);
+ thread.setPriority(Thread.MAX_PRIORITY);
+ thread.start();
+ }
+ }
+
+ public void stop() {
+ if (thread != null) {
+ thread.interrupt();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ started.set(false);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTargetSelf.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark evaluates INDY performance under dynamic target updates.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteSetTargetSelf {
+
+ /*
+ * Implementation notes:
+ * - This test makes sense for mutable and volatile call sites only
+ * - Multiple threads are calling the same callsite, and each call is swapping the target.
+ * - Additional baseline includes "raw" test, calling callsite's MH directly
+ *
+ * - NOTE: invalidating shared target callsite is very bad with multiple threads.
+ * I.e. this test is inherently non-scalable.
+ */
+
+ private static CallSite cs;
+
+ private static MethodHandle doCall1;
+ private static MethodHandle doCall2;
+
+ static {
+ try {
+ doCall1 = MethodHandles.lookup().findVirtual(CallSiteSetTargetSelf.class, "call1", MethodType.methodType(int.class));
+ doCall2 = MethodHandles.lookup().findVirtual(CallSiteSetTargetSelf.class, "call2", MethodType.methodType(int.class));
+ cs = new MutableCallSite(doCall1);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private int i1;
+ private int i2;
+
+ public int call1() {
+ cs.setTarget(doCall2);
+ return i1++;
+ }
+
+ public int call2() {
+ cs.setTarget(doCall1);
+ return i2++;
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return (int) cs.getTarget().invokeExact(this);
+ }
+
+ @Benchmark
+ public int testMutable() throws Throwable {
+ return (int) INDY_Mutable().invokeExact(this);
+ }
+
+ @Benchmark
+ public int testVolatile() throws Throwable {
+ return (int) INDY_Volatile().invokeExact(this);
+ }
+
+ /* =========================== INDY TRAMPOLINES ============================== */
+
+ private static MethodType MT_bsm() {
+ shouldNotCallThis();
+ return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+ }
+
+ private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+ }
+
+ private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+ }
+
+ private static MethodHandle INDY_Mutable() throws Throwable {
+ shouldNotCallThis();
+ return ((CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTargetSelf.class))).dynamicInvoker();
+ }
+
+ private static MethodHandle INDY_Volatile() throws Throwable {
+ shouldNotCallThis();
+ return ((CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTargetSelf.class))).dynamicInvoker();
+ }
+
+ public static CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteSetTarget.class) {
+ if (cs == null)
+ cs = new MutableCallSite(doCall1);
+ return cs;
+ }
+ }
+
+ public static CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteSetTarget.class) {
+ if (cs == null)
+ cs = new VolatileCallSite(doCall1);
+ return cs;
+ }
+ }
+
+ private static void shouldNotCallThis() {
+ // if this gets called, the transformation has not taken place
+ throw new AssertionError("this code should be statically transformed away by Indify");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteStable.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark evaluates INDY performance when call sites are not changed.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteStable {
+
+ /*
+ * Implementation notes:
+ * - Test is calling simple method via INDY
+ * - Additional baseline includes "raw" test, calling target method directly in virtual and static modes
+ */
+
+ private static java.lang.invoke.CallSite cs;
+
+ private static MethodHandle doCallMH;
+
+ static {
+ try {
+ doCallMH = MethodHandles.lookup().findVirtual(CallSiteStable.class, "doCall", MethodType.methodType(int.class, int.class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private int i;
+
+ public int doCall(int value) {
+ return value + 1;
+ }
+
+ public static int doCallStatic(int value) {
+ return value + 1;
+ }
+
+ @Benchmark
+ public void baselineVirtual() {
+ i = doCall(i);
+ }
+
+ @Benchmark
+ public void baselineStatic() {
+ i = doCallStatic(i);
+ }
+
+ @Benchmark
+ public void testConstant() throws Throwable {
+ i = (int) INDY_Constant().invokeExact(this, i);
+ }
+
+ @Benchmark
+ public void testMutable() throws Throwable {
+ i = (int) INDY_Mutable().invokeExact(this, i);
+ }
+
+ @Benchmark
+ public void testVolatile() throws Throwable {
+ i = (int) INDY_Volatile().invokeExact(this, i);
+ }
+
+ /* =========================== INDY TRAMPOLINES ============================== */
+
+ private static MethodType MT_bsm() {
+ shouldNotCallThis();
+ return MethodType.methodType(java.lang.invoke.CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+ }
+
+ private static MethodHandle MH_bsm_Constant() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Constant", MT_bsm());
+ }
+
+ private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+ }
+
+ private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+ shouldNotCallThis();
+ return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+ }
+
+ private static MethodHandle INDY_Constant() throws Throwable {
+ shouldNotCallThis();
+ return ((java.lang.invoke.CallSite) MH_bsm_Constant().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+ }
+ private static MethodHandle INDY_Mutable() throws Throwable {
+ shouldNotCallThis();
+ return ((java.lang.invoke.CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+ }
+ private static MethodHandle INDY_Volatile() throws Throwable {
+ shouldNotCallThis();
+ return ((java.lang.invoke.CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+ }
+
+ public static java.lang.invoke.CallSite bsm_Constant(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteStable.class) {
+ if (cs == null)
+ cs = new ConstantCallSite(doCallMH);
+ return cs;
+ }
+ }
+
+ public static java.lang.invoke.CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteStable.class) {
+ if (cs == null)
+ cs = new MutableCallSite(doCallMH);
+ return cs;
+ }
+ }
+
+ public static java.lang.invoke.CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+ synchronized (CallSiteStable.class) {
+ if (cs == null)
+ cs = new VolatileCallSite(doCallMH);
+ return cs;
+ }
+ }
+
+ private static void shouldNotCallThis() {
+ // if this gets called, the transformation has not taken place
+ throw new AssertionError("this code should be statically transformed away by Indify");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupAcquire.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.lookup/publicLookup() acquiring performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupAcquire {
+
+ /*
+ Implementation notes:
+ - this test assesses acquiring lookup object only
+ - baseline includes returning cached lookup object, i.e. measures infra overheads
+ - additional baseline includes allocating object to understand Lookup instantiation costs
+ - cached instance is static, because that provides (unbeatably) best performance
+ */
+
+ public static MethodHandles.Lookup cached;
+
+ @Setup
+ public void setup() {
+ cached = MethodHandles.lookup();
+ }
+
+ @Benchmark
+ public MethodHandles.Lookup baselineCached() throws Exception {
+ return cached;
+ }
+
+ @Benchmark
+ public MyLookup baselineNew() throws Exception {
+ return new MyLookup(Object.class, 1);
+ }
+
+ @Benchmark
+ public MethodHandles.Lookup testPublicLookup() throws Exception {
+ return MethodHandles.publicLookup();
+ }
+
+ @Benchmark
+ public MethodHandles.Lookup testLookup() throws Exception {
+ return MethodHandles.lookup();
+ }
+
+ /**
+ * Dummy Lookup-looking class.
+ * Lookup is final, and all constructors are private.
+ * This class mocks the hotpath.
+ */
+ private static class MyLookup {
+ private final Class<?> klass;
+ private final int mode;
+
+ public MyLookup(Class<?> klass, int i) {
+ this.klass = klass;
+ this.mode = i;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupDefaultFind.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.lookup() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupDefaultFind {
+
+ /*
+ Implementation notes:
+ - does not test findSpecial, since the privileges of this Bench is not enough to access private members
+ */
+
+ @Benchmark
+ public MethodHandle testConstructor() throws Exception {
+ return MethodHandles.lookup().findConstructor(Victim.class, MethodType.methodType(void.class));
+ }
+
+ @Benchmark
+ public MethodHandle testGetter() throws Exception {
+ return MethodHandles.lookup().findGetter(Victim.class, "field", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testSetter() throws Exception {
+ return MethodHandles.lookup().findSetter(Victim.class, "field", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testStatic() throws Exception {
+ return MethodHandles.lookup().findStatic(Victim.class, "staticWork", MethodType.methodType(int.class));
+ }
+
+ @Benchmark
+ public MethodHandle testStaticGetter() throws Exception {
+ return MethodHandles.lookup().findStaticGetter(Victim.class, "staticField", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testStaticSetter() throws Exception {
+ return MethodHandles.lookup().findStaticSetter(Victim.class, "staticField", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testVirtual() throws Exception {
+ return MethodHandles.lookup().findVirtual(Victim.class, "virtualWork", MethodType.methodType(int.class));
+ }
+
+ public static class Victim {
+
+ public static int staticField;
+ public int field;
+
+ public Victim() {
+ // do nothing
+ }
+
+ public int virtualWork() {
+ return 1;
+ }
+
+ public static int staticWork() {
+ return 1;
+ }
+
+ private int specialWork() {
+ return 1;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupPublicFind.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.publicLookup() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupPublicFind {
+
+ /*
+ Implementation notes:
+ - findSpecial is not tested, unable to do this with public lookup object
+ */
+
+ @Benchmark
+ public MethodHandle testConstructor() throws Exception {
+ return MethodHandles.publicLookup().findConstructor(Victim.class, MethodType.methodType(void.class));
+ }
+
+ @Benchmark
+ public MethodHandle testGetter() throws Exception {
+ return MethodHandles.publicLookup().findGetter(Victim.class, "field", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testSetter() throws Exception {
+ return MethodHandles.publicLookup().findSetter(Victim.class, "field", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testStatic() throws Exception {
+ return MethodHandles.publicLookup().findStatic(Victim.class, "staticWork", MethodType.methodType(int.class));
+ }
+
+ @Benchmark
+ public MethodHandle testStaticGetter() throws Exception {
+ return MethodHandles.publicLookup().findStaticGetter(Victim.class, "staticField", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testStaticSetter() throws Exception {
+ return MethodHandles.publicLookup().findStaticSetter(Victim.class, "staticField", int.class);
+ }
+
+ @Benchmark
+ public MethodHandle testVirtual() throws Exception {
+ return MethodHandles.publicLookup().findVirtual(Victim.class, "virtualWork", MethodType.methodType(int.class));
+ }
+
+ public static class Victim {
+
+ public static int staticField;
+ public int field;
+
+ public Victim() {
+ // do nothing
+ }
+
+ public int virtualWork() {
+ return 1;
+ }
+
+ public static int staticWork() {
+ return 1;
+ }
+
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsCollector.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asCollector() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsCollector {
+
+ /*
+ * Implementation notes:
+ * - simple array-parameter method is being called
+ * - baselineRaw calls method directly with dynamically instantiating the array
+ * - baselineCached calls method directly with pre-cached array
+ * - additional testCreate() test harnesses the collector acquisition performance
+ * - testCollector() can be faster than both baselines: it can wrapping array at all
+ */
+
+ public int i;
+ private static MethodHandle mh;
+ private static MethodHandle collectorMH;
+ private static int[] cachedArgs;
+
+ @Setup
+ public void setup() throws IllegalAccessException, NoSuchMethodException {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleAsCollector.class, "doWork", MethodType.methodType(void.class, int[].class));
+ collectorMH = mh.asCollector(int[].class, 5);
+ cachedArgs = new int[]{1, 2, 3, 4, 5};
+ }
+
+ @Benchmark
+ public void baselineMH() throws Throwable {
+ mh.invokeExact(this, new int[] { 1, 2, 3, 4, 5 });
+ }
+
+ @Benchmark
+ public void baselineMHCached() throws Throwable {
+ mh.invokeExact(this, cachedArgs);
+ }
+
+ @Benchmark
+ public void baselineRaw() throws Throwable {
+ doWork(new int[] { 1, 2, 3, 4, 5});
+ }
+
+ @Benchmark
+ public void baselineRawCached() throws Throwable {
+ doWork(cachedArgs);
+ }
+
+ @Benchmark
+ public MethodHandle testCreate() {
+ return mh.asCollector(int[].class, 5);
+ }
+
+ @Benchmark
+ public void testCollector() throws Throwable {
+ collectorMH.invokeExact(this, 1, 2, 3, 4, 5);
+ }
+
+ public void doWork(int[] args) {
+ for (int a : args) {
+ i += a;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsSpreader.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asSpreader() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsSpreader {
+
+ /*
+ * Implementation notes:
+ * - simple array-parameter method is being called
+ * - baselineRaw calls method directly with dynamically instantiating the array
+ * - baselineCached calls method directly with pre-cached array
+ * - additional testCreate() test harnesses the collector acquisition performance
+ * - testCollector() can be faster than both baselines: it can wrapping array at all
+ */
+
+ public int i;
+ private static MethodHandle mh;
+ private static MethodHandle spreaderMH;
+ private static int[] cachedArgs;
+
+ @Setup
+ public void setup() throws IllegalAccessException, NoSuchMethodException {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleAsSpreader.class, "doWork", MethodType.methodType(void.class, int.class, int.class, int.class, int.class, int.class));
+ spreaderMH = mh.asSpreader(int[].class, 5);
+ cachedArgs = new int[]{1, 2, 3, 4, 5};
+ }
+
+ @Benchmark
+ public void baselineMH() throws Throwable {
+ mh.invokeExact(this, 1, 2, 3, 4, 5);
+ }
+
+ @Benchmark
+ public void baselineRaw() throws Throwable {
+ doWork(1, 2, 3, 4, 5);
+ }
+
+ @Benchmark
+ public MethodHandle testCreate() {
+ return mh.asSpreader(int[].class, 5);
+ }
+
+ @Benchmark
+ public void testSpreader() throws Throwable {
+ spreaderMH.invokeExact(this, new int[] { 1, 2, 3, 4, 5 });
+ }
+
+ @Benchmark
+ public void testSpreaderCached() throws Throwable {
+ spreaderMH.invokeExact(this, cachedArgs);
+ }
+
+ public void doWork(int arg1, int arg2, int arg3, int arg4, int arg5) {
+ i += (arg1 + arg2 + arg3 + arg4 + arg5);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsVarargsCollector.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asVarargCollector() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsVarargsCollector {
+
+ /*
+ * Implementation notes:
+ * - simple array-parameter method is being called
+ * - baselineRaw calls method directly with dynamically instantiating the array
+ * - baselineCached calls method directly with pre-cached array
+ * - additional testCreate() test harnesses the collector acquisition performance
+ * - testCollector() can be faster than both baselines: it can wrapping array at all
+ */
+
+ public int i;
+ private static MethodHandle mh;
+ private static MethodHandle collectorMH;
+ private static int[] cachedArgs;
+
+ @Setup
+ public void setup() throws IllegalAccessException, NoSuchMethodException {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleAsVarargsCollector.class, "doWork", MethodType.methodType(void.class, int[].class));
+ collectorMH = mh.asVarargsCollector(int[].class);
+ cachedArgs = new int[]{1, 2, 3, 4, 5};
+ }
+
+ @Benchmark
+ public void baselineMH() throws Throwable {
+ mh.invoke(this, new int[] { 1, 2, 3, 4, 5 });
+ }
+
+ @Benchmark
+ public void baselineMHCached() throws Throwable {
+ mh.invoke(this, cachedArgs);
+ }
+
+ @Benchmark
+ public void baselineRaw() throws Throwable {
+ doWork(1, 2, 3, 4, 5);
+ }
+
+ @Benchmark
+ public void baselineRawCached() throws Throwable {
+ doWork(cachedArgs);
+ }
+
+ @Benchmark
+ public MethodHandle testCreate() {
+ return mh.asVarargsCollector(int[].class);
+ }
+
+ @Benchmark
+ public void testCollector() throws Throwable {
+ collectorMH.invoke(this, 1, 2, 3, 4, 5);
+ }
+
+ public void doWork(int... args) {
+ for (int a : args) {
+ i += a;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBasicInvoke.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark to assess basic MethodHandle performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBasicInvoke {
+
+ /*
+ * Implementation notes:
+ * - this is a very basic test, does not do any parameter conversion (in fact, no parameters at all)
+ * - baselines include calling method directly, and doing the same via reflection
+ * - baselineRaw is known to be super-fast with good inlining
+ */
+
+ private int i;
+ private static MethodHandle mh;
+ private static Method ref;
+ private static MethodHandle mhUnreflect;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleBasicInvoke.class, "doWork", MethodType.methodType(int.class));
+
+ ref = MethodHandleBasicInvoke.class.getMethod("doWork");
+ ref.setAccessible(true);
+
+ mhUnreflect = MethodHandles.lookup().unreflect(ref);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork();
+ }
+
+ @Benchmark
+ public int baselineReflect() throws Throwable {
+ return (int) ref.invoke(this);
+ }
+
+ @Benchmark
+ public int testMH_Plain_Invoke() throws Throwable {
+ return (int) mh.invoke(this);
+ }
+
+ @Benchmark
+ public int testMH_Plain_Exact() throws Throwable {
+ return (int) mh.invokeExact(this);
+ }
+
+ @Benchmark
+ public int testMH_Unreflect_Invoke() throws Throwable {
+ return (int) mhUnreflect.invoke(this);
+ }
+
+ @Benchmark
+ public int testMH_Unreflect_Exact() throws Throwable {
+ return (int) mhUnreflect.invokeExact(this);
+ }
+
+ public int doWork() {
+ return i++;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToBinding.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.bindTo() binding performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBindToBinding {
+
+ /*
+ Implementation notes:
+ - calls static method to avoid binding "this"
+ - tests binding costs with multiple depth (C1, C2, C3)
+ - baseline includes naive side effect store
+ - lowering the binding cost will minimise both the spread between C1/C2/C3 and difference towards baseline
+ - this test performance will never reach the baseline
+ */
+
+ private MethodHandle mhOrig;
+
+ @Setup
+ public void setup() throws Throwable {
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandleBindToBinding.class, "doWork",
+ MethodType.methodType(Integer.class, Integer.class, Integer.class, Integer.class));
+ }
+
+ @Benchmark
+ public Object baselineRaw() {
+ return mhOrig;
+ }
+
+ @Benchmark
+ public Object testBind_C1() throws Throwable {
+ MethodHandle mhCurry1 = mhOrig.bindTo(1);
+ return mhCurry1;
+ }
+
+ @Benchmark
+ public Object testBind_C2() throws Throwable {
+ MethodHandle mhCurry1 = mhOrig.bindTo(1);
+ MethodHandle mhCurry2 = mhCurry1.bindTo(2);
+ return mhCurry2;
+ }
+
+ @Benchmark
+ public Object testBind_C3() throws Throwable {
+ MethodHandle mhCurry1 = mhOrig.bindTo(1);
+ MethodHandle mhCurry2 = mhCurry1.bindTo(2);
+ MethodHandle mhCurry3 = mhCurry2.bindTo(3);
+ return mhCurry3;
+ }
+
+ public static Integer doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToCurry.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses currying with MethodHandle.bindTo() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBindToCurry {
+
+ /*
+ Implementation notes:
+ - calls static method to avoid binding "this"
+ - tests the performance of gradually curried methods, hoping for compiler to optimize
+ - arguments are volatile, to break optimistic CSE happening before the actual call
+ - using invokeExact and Integers to skip argument conversions
+ - baseline includes calling the method directly, and this is known to be super-fast due to inlining
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mhCurry1;
+ private MethodHandle mhCurry2;
+ private MethodHandle mhCurry3;
+
+ private volatile Integer arg1 = 1;
+ private volatile Integer arg2 = 2;
+ private volatile Integer arg3 = 3;
+
+ @Setup
+ public void setup() throws Throwable {
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandleBindToCurry.class, "doWork",
+ MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ mhCurry1 = mhOrig.bindTo(arg1);
+ mhCurry2 = mhCurry1.bindTo(arg2);
+ mhCurry3 = mhCurry2.bindTo(arg3);
+ }
+
+ @Benchmark
+ public int baselineRaw() {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_C0() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_C1() throws Throwable {
+ return (int) mhCurry1.invokeExact(arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_C2() throws Throwable {
+ return (int) mhCurry2.invokeExact(arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_C3() throws Throwable {
+ return (int) mhCurry3.invokeExact();
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertBoxing.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks autoboxing conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertBoxing {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling static method as to minimize virtual dispatch overheads.
+ */
+
+ private Integer valueBoxed;
+ private int valueUnboxed;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findStatic(MethodHandleConvertBoxing.class, "target", MethodType.methodType(int.class, int.class));
+ newType = MethodType.methodType(int.class, Integer.class);
+ valueBoxed = 42;
+ valueUnboxed = 42;
+ }
+
+ @Benchmark
+ public int baselineExact() throws Throwable {
+ return (int) mh.invokeExact(valueUnboxed);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(int.class, Integer.class));
+ }
+
+ @Benchmark
+ public int test_3_Call() throws Throwable {
+ return (int) mh.invoke(valueBoxed);
+ }
+
+ public static int target(int value) {
+ return value + 1;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertCast.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the casts are applied.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertCast {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling static method as to minimize virtual dispatch overheads.
+ */
+
+ private A instanceA;
+ private B instanceB;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findStatic(MethodHandleConvertCast.class, "target", MethodType.methodType(A.class, A.class));
+ newType = MethodType.methodType(A.class, B.class);
+ instanceA = new A();
+ instanceB = new B();
+ }
+
+ @Benchmark
+ public A baselineExact() throws Throwable {
+ return (A) mh.invokeExact(instanceA);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(A.class, B.class));
+ }
+
+ @Benchmark
+ public A test_3_Call() throws Throwable {
+ return (A) mh.invoke(instanceB);
+ }
+
+ public static A target(A value) {
+ return value;
+ }
+
+ public static class A {}
+ public static class B extends A { }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnPrimitive.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: void -> int.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnPrimitive {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+ * This test should be executed in non-shared mode.
+ */
+
+ public int value;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnPrimitive.class, "target", MethodType.methodType(void.class));
+ newType = MethodType.methodType(int.class, MethodHandleConvertReturnPrimitive.class);
+ }
+
+ @Benchmark
+ public void baselineExact() throws Throwable {
+ mh.invokeExact(this);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(int.class, MethodHandleConvertReturnPrimitive.class));
+ }
+
+ @Benchmark
+ public int test_3_Call() throws Throwable {
+ return (int) mh.invoke(this);
+ }
+
+ public void target() {
+ value++;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnReference.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: void -> Integer.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnReference {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+ * This test should be executed in non-shared mode.
+ */
+
+ public int value;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnReference.class, "target", MethodType.methodType(void.class));
+ newType = MethodType.methodType(Integer.class, MethodHandleConvertReturnReference.class);
+ }
+
+ @Benchmark
+ public void baselineExact() throws Throwable {
+ mh.invokeExact(this);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(Integer.class, MethodHandleConvertReturnReference.class));
+ }
+
+ @Benchmark
+ public Object test_3_Call() throws Throwable {
+ return mh.invoke(this);
+ }
+
+ public void target() {
+ value++;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnVoid.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: int -> void.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnVoid {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+ * This test should be executed in non-shared mode.
+ */
+
+ public int value;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnVoid.class, "target", MethodType.methodType(int.class));
+ newType = MethodType.methodType(void.class, MethodHandleConvertReturnVoid.class);
+ }
+
+ @Benchmark
+ public int baselineExact() throws Throwable {
+ return (int) mh.invokeExact(this);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(void.class, MethodHandleConvertReturnVoid.class));
+ }
+
+ @Benchmark
+ public void test_3_Call() throws Throwable {
+ mh.invoke(this);
+ }
+
+ public int target() {
+ return value++;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertUnboxing.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the unboxing conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertUnboxing {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling static method as to minimize virtual dispatch overheads.
+ */
+
+ private Integer valueBoxed;
+ private int valueUnboxed;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findStatic(MethodHandleConvertUnboxing.class, "target", MethodType.methodType(int.class, Integer.class));
+ newType = MethodType.methodType(int.class, int.class);
+ valueBoxed = 42;
+ valueUnboxed = 42;
+ }
+
+ @Benchmark
+ public int baselineExact() throws Throwable {
+ return (int) mh.invokeExact(valueBoxed);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(int.class, int.class));
+ }
+
+ @Benchmark
+ public int test_3_Call() throws Throwable {
+ return (int) mh.invoke(valueUnboxed);
+ }
+
+ public static int target(Integer value) {
+ return value + 1;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertWidening.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the widening conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertWidening {
+
+ /*
+ * Implementation notes:
+ *
+ * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+ *
+ * The test is subdivided into three subtests, gradually doing more work:
+ * - 1_Convert: calls MH.asType to do actual conversion
+ * - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+ * - 3_Call: calls MH.invoke, requesting argument conversion
+ *
+ * Calling static method as to minimize virtual dispatch overheads.
+ */
+
+ private long valueLong;
+ private int valueInt;
+
+ private MethodHandle mh;
+ private MethodType newType;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findStatic(MethodHandleConvertWidening.class, "target", MethodType.methodType(long.class, long.class));
+ newType = MethodType.methodType(long.class, int.class);
+ valueInt = 42;
+ valueLong = 42L;
+ }
+
+ @Benchmark
+ public long baselineExact() throws Throwable {
+ return (long) mh.invokeExact(valueLong);
+ }
+
+ @Benchmark
+ public MethodHandle test_1_Convert() throws Throwable {
+ return mh.asType(newType);
+ }
+
+ @Benchmark
+ public MethodHandle test_2_MTConvert() throws Throwable {
+ return mh.asType(MethodType.methodType(long.class, int.class));
+ }
+
+ @Benchmark
+ public long test_3_Call() throws Throwable {
+ return (long) mh.invoke(valueInt);
+ }
+
+ public static long target(long value) {
+ return value + 1;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleInvokeWithArgs.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark to assess basic MethodHandle performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleInvokeWithArgs {
+
+ /*
+ * Implementation notes:
+ * - this is a very basic test, does not do any parameter conversion (in fact, no parameters at all)
+ * - baselines include calling method directly, and doing the same via reflection
+ * - baselineRaw is known to be super-fast with good inlining
+ */
+
+ private int i;
+ private static MethodHandle mh;
+
+ private Integer a = 42;
+
+ @Setup
+ public void setup() throws Throwable {
+ mh = MethodHandles.lookup().findVirtual(MethodHandleInvokeWithArgs.class, "doWork", MethodType.methodType(int.class, Integer.class));
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(a);
+ }
+
+ @Benchmark
+ public int baselineInvoke() throws Throwable {
+ return (int) mh.invoke(this, a);
+ }
+
+ @Benchmark
+ public int baselineInvokeExact() throws Throwable {
+ return (int) mh.invokeExact(this, a);
+ }
+
+ @Benchmark
+ public int testInvoke_WithArguments() throws Throwable {
+ return (int) mh.invokeWithArguments(this, a);
+ }
+
+ public int doWork(Integer a) {
+ return i += a;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesAsIFInstance.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark evaluates the performance of MethodHandleProxies.*
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleProxiesAsIFInstance {
+
+ /**
+ * Implementation notes:
+ * - asInterfaceInstance() can only target static MethodHandle (adapters needed to call instance method?)
+ * - baselineCompute will quickly degrade to GC test, if escape analysis is unable to spare the allocation
+ * - testCreate* will always be slower if allocation is not eliminated; baselineAllocCompute makes sure allocation is present
+ */
+
+ public int i;
+
+ private MethodHandle target;
+ private Doable precreated;
+
+ @Setup
+ public void setup() throws Throwable {
+ target = MethodHandles.lookup().findStatic(MethodHandleProxiesAsIFInstance.class, "doWork", MethodType.methodType(int.class, int.class));
+ precreated = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+ }
+
+ @Benchmark
+ public Doable testCreate() {
+ Doable doable = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+ return doable; // make sure allocation happens
+ }
+
+ @Benchmark
+ public Doable testCreateCall() {
+ Doable doable = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+ i = doable.doWork(i); // make sure computation happens
+ return null; // let allocation be eliminated
+ }
+
+ @Benchmark
+ public Doable testCall() {
+ i = precreated.doWork(i); // make sure computation happens
+ return precreated;
+ }
+
+ @Benchmark
+ public Doable baselineCompute() {
+ Doable doable = new Doable() {
+ @Override
+ public int doWork(int i) {
+ return MethodHandleProxiesAsIFInstance.doWork(i);
+ }
+ };
+
+ i = doable.doWork(i); // make sure computation happens
+ return null; // let allocation be eliminated
+ }
+
+ @Benchmark
+ public Doable baselineAllocCompute() {
+ Doable doable = new Doable() {
+ @Override
+ public int doWork(int i) {
+ return MethodHandleProxiesAsIFInstance.doWork(i);
+ }
+ };
+
+ i = doable.doWork(i); // make sure computation happens
+ return doable; // make sure allocation happens
+ }
+
+ public static int doWork(int i) {
+ return i + 1;
+ }
+
+ public interface Doable {
+ int doWork(int i);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesSuppl.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark evaluates the performance of MethodHandleProxies.* supplementary methods.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleProxiesSuppl {
+
+ /*
+ * Implementation notes:
+ * - This is a very naive test, evaluates the performance of service methods.
+ */
+
+ private Doable instance;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodHandle target = MethodHandles.lookup().findStatic(MethodHandleProxiesSuppl.class, "doWork", MethodType.methodType(int.class, int.class));
+ instance = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+ }
+
+ @Benchmark
+ public Object baselineReturn() {
+ return instance;
+ }
+
+ @Benchmark
+ public boolean testIsWrapperInstance() {
+ return MethodHandleProxies.isWrapperInstance(instance);
+ }
+
+ @Benchmark
+ public Class<?> testInstanceType() {
+ return MethodHandleProxies.wrapperInstanceType(instance);
+ }
+
+ @Benchmark
+ public MethodHandle testInstanceTarget() {
+ return MethodHandleProxies.wrapperInstanceTarget(instance);
+ }
+
+ public static int doWork(int i) {
+ throw new IllegalStateException("Can't touch this");
+ }
+
+ public interface Doable {
+ int doWork(int i);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementGetter.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the performance of MethodHandles.arrayElementGetter
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesArrayElementGetter {
+
+ /**
+ * Implementation notes:
+ * - creating simple array, and accessing the middle element
+ * - might have done iteration over array, but that will measure pipelining effects instead
+ * - volatile modifier on array breaks the DCE, which would otherwise eliminate the array load
+ * - the rationale for array size and access pattern is coherent to SetterBench
+ */
+
+ private static final int SIZE = 1024;
+ private static final int POS = SIZE/2;
+
+ private static MethodHandle mh;
+ private volatile int[] array;
+
+ @Setup
+ public void setup() throws Throwable {
+ array = new int[SIZE];
+ for (int i = 0; i < SIZE; i++) {
+ array[i] = i;
+ }
+ mh = MethodHandles.arrayElementGetter(int[].class);
+ }
+
+ @Benchmark
+ public MethodHandle testCreate() {
+ return MethodHandles.arrayElementGetter(int[].class);
+ }
+
+ @Benchmark
+ public int baselineRaw() {
+ return access(array, POS);
+ }
+
+ @Benchmark
+ public int testGetter() throws Throwable {
+ return (int) mh.invoke(array, POS);
+ }
+
+ public int access(int[] array, int pos) {
+ return array[pos];
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementSetter.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the performance of MethodHandles.arrayElementSetter
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesArrayElementSetter {
+
+ /**
+ * Implementation notes:
+ * - creating simple array, and accessing the middle element
+ * - might have done iteration over array, but that will measure pipelining effects instead
+ * - volatile modifier on array breaks the DCE, which would otherwise eliminate the array store
+ * - the array is not shared to prevent true sharing
+ * - the array is large enough to prevent false sharing
+ */
+
+ private static final int SIZE = 1024;
+ private static final int POS = SIZE/2;
+
+ private static MethodHandle mh;
+ private volatile int[] array;
+
+ @Setup
+ public void setup() throws Throwable {
+ array = new int[SIZE];
+ for (int i = 0; i < SIZE; i++) {
+ array[i] = i;
+ }
+ mh = MethodHandles.arrayElementSetter(int[].class);
+ }
+
+ @Benchmark
+ public MethodHandle testCreate() {
+ return MethodHandles.arrayElementSetter(int[].class);
+ }
+
+ @Benchmark
+ public void baselineRaw() {
+ access(array, POS, 1);
+ }
+
+ @Benchmark
+ public void testSetter() throws Throwable {
+ mh.invoke(array, POS, 1);
+ }
+
+ public void access(int[] array, int pos, int v) {
+ array[pos] = v;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesCatchException.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.catchException() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesCatchException {
+
+ /**
+ * Implementation notes:
+ * - emulating instance method handles because of current issue with instance methods
+ * - exception is cached to harness the MH code, not exception instantiation
+ * - measuring two modes:
+ * a) always going through normal code path;
+ * b) always going through exceptional one
+ * - baselines do the same thing in pure Java
+ */
+
+ private static final MyException MY_EXCEPTION = new MyException();
+
+ private int i1;
+ private int i2;
+
+ private static MethodHandle methNormal;
+ private static MethodHandle methExceptional;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodHandle bodyNormal = MethodHandles.lookup()
+ .findStatic(MethodHandlesCatchException.class, "doWorkNormal",
+ MethodType.methodType(void.class, MethodHandlesCatchException.class));
+ MethodHandle bodyExceptional = MethodHandles.lookup()
+ .findStatic(MethodHandlesCatchException.class, "doWorkExceptional",
+ MethodType.methodType(void.class, MethodHandlesCatchException.class));
+ MethodHandle fallback = MethodHandles.lookup()
+ .findStatic(MethodHandlesCatchException.class, "fallback",
+ MethodType.methodType(void.class, MyException.class, MethodHandlesCatchException.class));
+
+ methNormal = MethodHandles.catchException(bodyNormal, MyException.class, fallback);
+ methExceptional = MethodHandles.catchException(bodyExceptional, MyException.class, fallback);
+ }
+
+ @Benchmark
+ public void baselineNormal() {
+ try {
+ doWorkNormal(this);
+ } catch (MyException e) {
+ fallback(e, this);
+ }
+ }
+
+ @Benchmark
+ public void baselineExceptional() {
+ try {
+ doWorkExceptional(this);
+ } catch (MyException e) {
+ fallback(e, this);
+ }
+ }
+
+ @Benchmark
+ public void testNormal() throws Throwable {
+ methNormal.invokeExact(this);
+ }
+
+ @Benchmark
+ public void testExceptional() throws Throwable {
+ methExceptional.invokeExact(this);
+ }
+
+
+ public static void doWorkNormal(MethodHandlesCatchException inst) throws MyException {
+ inst.i1++;
+ }
+
+ public static void doWorkExceptional(MethodHandlesCatchException inst) throws MyException {
+ inst.i1++;
+ throw MY_EXCEPTION;
+ }
+
+ public static void fallback(MyException ex, MethodHandlesCatchException inst) {
+ inst.i2++;
+ }
+
+ public static class MyException extends Exception {
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesConstant.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.constant() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesConstant {
+
+ private MethodHandle mh;
+ private Integer cachedInt;
+
+ @Setup
+ public void setup() {
+ cachedInt = 42;
+ mh = MethodHandles.constant(Integer.class, 42);
+ }
+
+ @Benchmark
+ public Integer baselineReturn() {
+ return cachedInt;
+ }
+
+ @Benchmark
+ public MethodHandle interCreate() throws Throwable {
+ return MethodHandles.constant(Integer.class, 42);
+ }
+
+ @Benchmark
+ public MethodHandle interCreateCached() throws Throwable {
+ return MethodHandles.constant(Integer.class, cachedInt);
+ }
+
+ @Benchmark
+ public Integer testInvoke() throws Throwable {
+ return (Integer) mh.invoke();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesDropArguments.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.dropArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesDropArguments {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ */
+
+ private MethodHandle orig;
+ private MethodHandle modified;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ orig = MethodHandles.lookup().findStatic(MethodHandlesDropArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ modified = MethodHandles.dropArguments(orig, 0, int.class);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int baselineMH() throws Throwable {
+ return (int) orig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke() throws Throwable {
+ return (int) modified.invokeExact(0, arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public MethodHandle interCreate() throws Throwable {
+ return MethodHandles.dropArguments(orig, 0, int.class);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesExactInvoker.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.exactInvoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesExactInvoker {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ * - tested method should perform no worse than the baseline
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mnInvoke;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+ mnInvoke = MethodHandles.exactInvoker(mt);
+ }
+
+ @Benchmark
+ public int baselineOrig() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoker() throws Throwable {
+ return (int) mnInvoke.invokeExact(mhOrig, arg1, arg2, arg3);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterArgs.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.filterArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFilterArgs {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ * - the filter is empty to measure infra costs, not the filter itself
+ * - baselines should be comparable for each method if optimized enough
+ */
+
+ private MethodHandle orig;
+ private MethodHandle modified1;
+ private MethodHandle modified2;
+ private MethodHandle modified3;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ orig = MethodHandles.lookup().findStatic(MethodHandlesFilterArgs.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ MethodHandle filter = MethodHandles.lookup().findStatic(MethodHandlesFilterArgs.class, "filter", MethodType.methodType(Integer.class, Integer.class));
+ modified1 = MethodHandles.filterArguments(orig, 0, filter);
+ modified2 = MethodHandles.filterArguments(orig, 0, filter, filter);
+ modified3 = MethodHandles.filterArguments(orig, 0, filter, filter, filter);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int baselineRawConvert() throws Throwable {
+ return doWork(filter(arg1), filter(arg2), filter(arg3));
+ }
+
+ @Benchmark
+ public int baselineMH() throws Throwable {
+ return (int) orig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int baselineMHConvert() throws Throwable {
+ return (int) orig.invokeExact(filter(arg1), filter(arg2), filter(arg3));
+ }
+
+ @Benchmark
+ public int testInvoke_M1() throws Throwable {
+ return (int) modified1.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_M2() throws Throwable {
+ return (int) modified2.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoke_M3() throws Throwable {
+ return (int) modified3.invokeExact(arg1, arg2, arg3);
+ }
+
+ public static Integer filter(Integer a) {
+ return a;
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterReturn.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.filterReturnValue() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFilterReturn {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ */
+
+ private MethodHandle orig;
+ private MethodHandle filter;
+ private MethodHandle modified;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ orig = MethodHandles.lookup().findStatic(MethodHandlesFilterReturn.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ filter = MethodHandles.lookup().findStatic(MethodHandlesFilterReturn.class, "filter", MethodType.methodType(int.class, int.class));
+ modified = MethodHandles.filterReturnValue(orig, filter);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return filter(doWork(arg1, arg2, arg3));
+ }
+
+ @Benchmark
+ public int baselineMH() throws Throwable {
+ return filter((int) orig.invokeExact(arg1, arg2, arg3));
+ }
+
+ @Benchmark
+ public int testInvoke() throws Throwable {
+ return (int) modified.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public MethodHandle interCreate() throws Throwable {
+ return MethodHandles.filterReturnValue(orig, filter);
+ }
+
+ public static int filter(int a) {
+ return a * 2;
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFoldArguments.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.foldArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFoldArguments {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mhFolded;
+ private MethodHandle mhTarget;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesFoldArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ mhFolded = MethodHandles.lookup().findStatic(MethodHandlesFoldArguments.class, "doWork", MethodType.methodType(int.class, int.class, Integer.class, Integer.class, Integer.class));
+ mhTarget = MethodHandles.foldArguments(mhFolded, mhOrig);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Raw() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Folded() throws Throwable {
+ return (int) mhFolded.invokeExact(0, arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Target() throws Throwable {
+ return (int) mhTarget.invokeExact(arg1, arg2, arg3);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+ public static int doWork(int r, Integer a, Integer b, Integer c) {
+ return r;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesGuardWithTest.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.guardWithTest() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesGuardWithTest {
+
+ /**
+ * Implementation notes:
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ * - tested method should perform no worse than the baseline
+ */
+
+ private MethodHandle mhWork1;
+ private MethodHandle mhWork2;
+ private MethodHandle guard;
+ private boolean choice;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+ mhWork1 = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "doWork1", mt);
+ mhWork2 = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "doWork2", mt);
+
+ MethodHandle chooser = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "chooser", MethodType.methodType(boolean.class));
+ guard = MethodHandles.guardWithTest(chooser, mhWork1, mhWork2);
+ }
+
+ @Benchmark
+ public int baselineManual() throws Throwable {
+ if (choice) {
+ return (int) mhWork1.invokeExact(this, arg1, arg2, arg3);
+ } else {
+ return (int) mhWork2.invokeExact(this, arg1, arg2, arg3);
+ }
+ }
+
+ @Benchmark
+ public int testInvoke() throws Throwable {
+ return (int) guard.invoke(this, arg1, arg2, arg3);
+ }
+
+ public boolean chooser() {
+ choice = !choice;
+ return choice;
+ }
+
+ public int doWork1(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+ public int doWork2(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*c + b) + a);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesIdentity.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.identity() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesIdentity {
+
+ private MethodHandle mh;
+ private Object cachedArg;
+
+ @Setup
+ public void setup() {
+ cachedArg = new Object();
+ mh = MethodHandles.identity(Object.class);
+ }
+
+ @Benchmark
+ public Object baselineRaw() throws Throwable {
+ return new Object();
+ }
+
+ @Benchmark
+ public Object baselineRawCached() throws Throwable {
+ return cachedArg;
+ }
+
+ @Benchmark
+ public Object testInvoke() throws Throwable {
+ return mh.invoke(new Object());
+ }
+
+ @Benchmark
+ public Object testInvokeCached() throws Throwable {
+ return mh.invoke(cachedArg);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInsertArguments.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.insertArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesInsertArguments {
+
+ /**
+ * Implementation notes:
+ * - this test is similar to MethodHandleBindToCurryBench
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mhCurry1;
+ private MethodHandle mhCurry2;
+ private MethodHandle mhCurry3;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+ mhCurry1 = MethodHandles.insertArguments(mhOrig, 0, arg1);
+ mhCurry2 = MethodHandles.insertArguments(mhOrig, 0, arg1, arg2);
+ mhCurry3 = MethodHandles.insertArguments(mhOrig, 0, arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_C0() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_C1() throws Throwable {
+ return (int) mhCurry1.invokeExact(arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_C2() throws Throwable {
+ return (int) mhCurry2.invokeExact(arg3);
+ }
+
+ @Benchmark
+ public int invoke_C3() throws Throwable {
+ return (int) mhCurry3.invokeExact();
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInvoker.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.invoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesInvoker {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ * - tested method should perform no worse than the baseline
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mnInvoke;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+ mnInvoke = MethodHandles.invoker(mt);
+ }
+
+ @Benchmark
+ public int baselineOrig() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoker() throws Throwable {
+ return (int) mnInvoke.invokeExact(mhOrig, arg1, arg2, arg3);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesPermuteArguments.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.permuteArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesPermuteArguments {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mhNoReorder;
+ private MethodHandle mhReverse;
+ private MethodHandle mhShift;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+
+ @Setup
+ public void setup() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesPermuteArguments.class, "doWork", mt);
+ mhNoReorder = MethodHandles.permuteArguments(mhOrig, mt, 0, 1, 2);
+ mhReverse = MethodHandles.permuteArguments(mhOrig, mt, 2, 1, 0);
+ mhShift = MethodHandles.permuteArguments(mhOrig, mt, 2, 0, 1);
+ }
+
+ @Benchmark
+ public int baselineRaw() throws Throwable {
+ return doWork(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Raw() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_NoReorder() throws Throwable {
+ return (int) mhNoReorder.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Reverse() throws Throwable {
+ return (int) mhReverse.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int invoke_Shift() throws Throwable {
+ return (int) mhShift.invokeExact(arg1, arg2, arg3);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesSpreadInvoker.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.spreadInvoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesSpreadInvoker {
+
+ /**
+ * Implementation notes:
+ * - calling static method to have consistent arg list without receiver type
+ * - using volatile ints as arguments to prevent opportunistic optimizations
+ * - using Integers to limit argument conversion costs
+ * - tested method should perform no worse than the baseline
+ */
+
+ private MethodHandle mhOrig;
+ private MethodHandle mnInvoke;
+
+ private volatile Integer arg1 = 42;
+ private volatile Integer arg2 = 43;
+ private volatile Integer arg3 = 44;
+ private Object[] cachedArgs;
+
+ @Setup
+ public void setup() throws Throwable {
+ cachedArgs = new Integer[]{arg1, arg2, arg3};
+
+ MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+ mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+ mnInvoke = MethodHandles.spreadInvoker(mt, 0);
+ }
+
+ @Benchmark
+ public int baselineOrig() throws Throwable {
+ return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+ }
+
+ @Benchmark
+ public int testInvoker() throws Throwable {
+ return (int) mnInvoke.invokeExact(mhOrig, new Object[] { arg1, arg2, arg3 });
+ }
+
+ @Benchmark
+ public int testInvokerCached() throws Throwable {
+ return (int) mnInvoke.invokeExact(mhOrig, cachedArgs);
+ }
+
+ public static int doWork(Integer a, Integer b, Integer c) {
+ return 31*(31*(31*a + b) + c);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesThrowException.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.throwException() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesThrowException {
+
+ /**
+ * Implementation notes:
+ * - exceptions have a thorough call back to benchmark instance to prevent elimination (against dumb JITs)
+ * - testing in plain and cached modes
+ * - baselines do the same thing, but in pure Java
+ */
+
+ public int flag;
+ private MethodHandle mh;
+ private MyException cachedException;
+
+ @Setup
+ public void setup() {
+ flag = 42;
+ cachedException = new MyException();
+ mh = MethodHandles.throwException(void.class, MyException.class);
+ }
+
+ @Benchmark
+ public int baselineRaw() {
+ try {
+ throw new MyException();
+ } catch (MyException my) {
+ return my.getFlag();
+ }
+ }
+
+ @Benchmark
+ public int baselineRawCached() {
+ try {
+ throw cachedException;
+ } catch (MyException my) {
+ return my.getFlag();
+ }
+ }
+
+ @Benchmark
+ public int testInvoke() throws Throwable {
+ try {
+ mh.invoke(new MyException());
+ throw new IllegalStateException("Should throw exception");
+ } catch (MyException my) {
+ return my.getFlag();
+ }
+ }
+
+ @Benchmark
+ public int testInvokeCached() throws Throwable {
+ try {
+ mh.invoke(cachedException);
+ throw new IllegalStateException("Should throw exception");
+ } catch (MyException my) {
+ return my.getFlag();
+ }
+ }
+
+ @Benchmark
+ public MethodHandle interCreate() {
+ return MethodHandles.throwException(void.class, MyException.class);
+ }
+
+ public class MyException extends Exception {
+
+ public int getFlag() {
+ return flag;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAcquire.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Assesses general MethodType performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeAcquire {
+
+ private MethodType pTypes;
+
+ @Setup
+ public void setup() {
+ pTypes = MethodType.methodType(A.class, B.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return pTypes;
+ }
+
+ @Benchmark
+ public MethodType testReturnVoid() {
+ return MethodType.methodType(void.class);
+ }
+
+ @Benchmark
+ public MethodType testReturnInt() {
+ return MethodType.methodType(int.class);
+ }
+
+ @Benchmark
+ public MethodType testReturnObject() {
+ return MethodType.methodType(Object.class);
+ }
+
+ @Benchmark
+ public MethodType testSinglePType() {
+ return MethodType.methodType(void.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType testMultiPType() {
+ return MethodType.methodType(void.class, A.class, B.class);
+ }
+
+ @Benchmark
+ public MethodType testMultiPType_Arg() {
+ return MethodType.methodType(void.class, pTypes);
+ }
+
+ public static class A {}
+ public static class B {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAppendParams.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.appendParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeAppendParams {
+
+ /**
+ * Implementation notes:
+ * - tests multiple cases, gradually appending more arguments
+ * - baselines include just returning the same method type, and calling with empty argument list
+ */
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType baselineNop() {
+ return mt.appendParameterTypes();
+ }
+
+ @Benchmark
+ public MethodType test_A1() {
+ return mt.appendParameterTypes(int.class);
+ }
+
+ @Benchmark
+ public MethodType test_A2() {
+ return mt.appendParameterTypes(int.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType test_A3() {
+ return mt.appendParameterTypes(int.class, int.class, int.class);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeParam.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.changeParameterType()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeChangeParam {
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType baselineSame() {
+ return mt.changeParameterType(1, int.class);
+ }
+
+ @Benchmark
+ public MethodType testChangeType() {
+ return mt.changeParameterType(1, Integer.class);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeReturn.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.changeReturnType()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeChangeReturn {
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType baselineSame() {
+ return mt.changeReturnType(void.class);
+ }
+
+ @Benchmark
+ public MethodType testChange() {
+ return mt.changeReturnType(Integer.class);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeDropParams.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.dropParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeDropParams {
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class, int.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType baselineSame() {
+ return mt.dropParameterTypes(0, 0);
+ }
+
+ @Benchmark
+ public MethodType testDrop_A1() {
+ return mt.dropParameterTypes(0, 1);
+ }
+
+ @Benchmark
+ public MethodType testDrop_A2() {
+ return mt.dropParameterTypes(0, 2);
+ }
+
+ @Benchmark
+ public MethodType testDrop_A3() {
+ return mt.dropParameterTypes(0, 3);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeGenerify.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.erase() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeGenerify {
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class, Integer.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType testGeneric() {
+ return mt.generic();
+ }
+
+ @Benchmark
+ public MethodType testWrapErase() {
+ return mt.wrap().erase();
+ }
+
+ @Benchmark
+ public MethodType testErase() {
+ return mt.erase();
+ }
+
+ @Benchmark
+ public MethodType testWrap() {
+ return mt.wrap();
+ }
+
+ @Benchmark
+ public MethodType testUnwrap() {
+ return mt.unwrap();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeInsertParams.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.insertParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeInsertParams {
+
+ private MethodType mt;
+
+ @Setup
+ public void setup() {
+ mt = MethodType.methodType(void.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType baselineRaw() {
+ return mt;
+ }
+
+ @Benchmark
+ public MethodType baselineSame() {
+ return mt.insertParameterTypes(0);
+ }
+
+ @Benchmark
+ public MethodType testInsert_A1() {
+ return mt.insertParameterTypes(0, int.class);
+ }
+
+ @Benchmark
+ public MethodType testInsert_A2() {
+ return mt.insertParameterTypes(0, int.class, int.class);
+ }
+
+ @Benchmark
+ public MethodType testInsert_A3() {
+ return mt.insertParameterTypes(0, int.class, int.class, int.class);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointAdhoc.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.SwitchPoint;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assessing SwitchPoint performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SwitchPointAdhoc {
+
+ /*
+ * Implementation notes:
+ * - this test asserts SwitchPoint performance in both valid and invalid cases
+ * - this test does not assert invalidation performance (hard to do with irreversible SwitchPoint)
+ * - raw baseline gives the idea for MethodHandle invocation cost
+ * - CS baseline gives the idea for additional dereference cost
+ */
+
+ private MethodHandle body1, body2;
+ private int i;
+ private java.lang.invoke.SwitchPoint sw1, sw2;
+ private CallSite cs;
+
+ @Setup
+ public void setup() throws NoSuchMethodException, IllegalAccessException {
+ sw1 = new java.lang.invoke.SwitchPoint();
+ sw2 = new java.lang.invoke.SwitchPoint();
+ SwitchPoint.invalidateAll(new SwitchPoint[]{sw2});
+ body1 = MethodHandles.lookup().findVirtual(SwitchPointAdhoc.class, "body1", MethodType.methodType(int.class, int.class));
+ body2 = MethodHandles.lookup().findVirtual(SwitchPointAdhoc.class, "body2", MethodType.methodType(int.class, int.class));
+ cs = new MutableCallSite(body1);
+ }
+
+ @Benchmark
+ public void baselineRaw() throws Throwable {
+ i = (int) body1.invoke(this, i);
+ }
+
+ @Benchmark
+ public void baselineCS() throws Throwable {
+ i = (int) cs.getTarget().invoke(this, i);
+ }
+
+ @Benchmark
+ public void testValid() throws Throwable {
+ MethodHandle handle = sw1.guardWithTest(body1, body2);
+ i = (int) handle.invoke(this, i);
+ }
+
+ @Benchmark
+ public void testInvalid() throws Throwable {
+ MethodHandle handle = sw2.guardWithTest(body1, body2);
+ i = (int) handle.invoke(this, i);
+ }
+
+ public int body1(int i) {
+ return i + 1;
+ }
+
+ public int body2(int i) {
+ return i + 1;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointGuard.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assessing SwitchPoint performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SwitchPointGuard {
+
+ /*
+ * Implementation notes:
+ * - this test asserts SwitchPoint performance in both valid and invalid cases
+ * - this test does not assert invalidation performance (hard to do with irreversible SwitchPoint)
+ * - raw baseline gives the idea for MethodHandle invocation cost
+ * - CS baseline gives the idea for additional dereference cost
+ */
+
+ private MethodHandle body1, body2;
+ private int i;
+ private SwitchPoint sw1, sw2;
+ private CallSite cs;
+ private MethodHandle guard1, guard2;
+
+ @Setup
+ public void setup() throws NoSuchMethodException, IllegalAccessException {
+ sw1 = new SwitchPoint();
+ sw2 = new SwitchPoint();
+ SwitchPoint.invalidateAll(new SwitchPoint[]{sw2});
+ body1 = MethodHandles.lookup().findVirtual(SwitchPointGuard.class, "body1", MethodType.methodType(int.class, int.class));
+ body2 = MethodHandles.lookup().findVirtual(SwitchPointGuard.class, "body2", MethodType.methodType(int.class, int.class));
+ guard1 = sw1.guardWithTest(body1, body2);
+ guard2 = sw2.guardWithTest(body1, body2);
+ cs = new MutableCallSite(body1);
+ }
+
+ @Benchmark
+ public void baselineRaw() throws Throwable {
+ i = (int) body1.invoke(this, i);
+ }
+
+ @Benchmark
+ public void baselineCS() throws Throwable {
+ i = (int) cs.getTarget().invoke(this, i);
+ }
+
+ @Benchmark
+ public void testValid() throws Throwable {
+ i = (int) guard1.invoke(this, i);
+ }
+
+ @Benchmark
+ public void testInvalid() throws Throwable {
+ i = (int) guard2.invoke(this, i);
+ }
+
+ public int body1(int i) {
+ return i + 1;
+ }
+
+ public int body2(int i) {
+ return i + 1;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Clazz {
+
+ /**
+ * Get constructor for this class through reflection
+ *
+ * @return
+ * @throws NoSuchMethodException
+ */
+ @Benchmark
+ public Constructor getConstructor() throws NoSuchMethodException {
+ return Clazz.class.getConstructor();
+ }
+
+ /**
+ * Get constructor for the String class through reflection, forcing full
+ * security check
+ *
+ * @return
+ * @throws NoSuchMethodException
+ */
+ @Benchmark
+ public Constructor getConstructorDifferentClassLoader() throws NoSuchMethodException {
+ return String.class.getConstructor();
+ }
+
+ /**
+ * Get the toString method through reflection on Clazz
+ *
+ * @return
+ */
+ @Benchmark
+ public Method getMethod() throws NoSuchMethodException {
+ return Clazz.class.getMethod("toString");
+ }
+
+ /**
+ * Get the toString method through reflection on String, forcing full
+ * security check
+ *
+ * @return
+ * @throws NoSuchMethodException
+ */
+ @Benchmark
+ public Method getMethodDifferentClassLoader() throws NoSuchMethodException {
+ return String.class.getMethod("toString");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/ClazzWithSecurityManager.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Policy;
+import java.security.URIParameter;
+
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+/**
+ * Reflection benchmark
+ *
+ * @author sfriberg
+ */
+@State(Scope.Benchmark)
+public class ClazzWithSecurityManager extends Clazz {
+
+ @Setup
+ public void setup() throws IOException, NoSuchAlgorithmException, URISyntaxException {
+ URI policyFile = ClazzWithSecurityManager.class.getResource("/jmh-security.policy").toURI();
+ Policy.setPolicy(Policy.getInstance("JavaPolicy", new URIParameter(policyFile)));
+ System.setSecurityManager(new SecurityManager());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/MethodInvoke.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring java.lang.reflect.Method.invoke speed.
+ * <p/>
+ * TODO: Add tests for virtual and interface methods.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodInvoke {
+
+ private Method staticMeth_0;
+ private Method staticMeth_6ref;
+ private Method staticMeth_6prim;
+
+ private Object[] args_0;
+ private Object[] args_6ref;
+ private Object[] args_6prim;
+
+ @Setup
+ public void setup() {
+ args_0 = new Object[]{};
+ args_6ref = new Object[]{ new Object(), new Object(),
+ new Object(), new Object(), new Object(), new Object()};
+ args_6prim = new Object[]{
+ new Integer(1), new Long(5L),
+ new Double(5.6d), new Float(23.11f),
+ Boolean.TRUE, new Character('d')
+ };
+
+ staticMeth_0 = getMethodWithName("staticMethodWithoutParams");
+ staticMeth_6ref = getMethodWithName("staticMethodWithSixObjectParams");
+ staticMeth_6prim = getMethodWithName("staticMethodWithSixPrimitiveParams");
+ }
+
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public static void staticMethodWithoutParams() {
+ // intentionally left blank
+ }
+
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public static void staticMethodWithSixObjectParams(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) {
+ // intentionally left blank
+ }
+
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public static void staticMethodWithSixPrimitiveParams(int i, long j, double d, float f, boolean z, char c) {
+ // intentionally left blank
+ }
+
+ /* inner method to get the method to invoke. */
+
+ private static Method getMethodWithName(String methodName) {
+ Method[] methodArray = MethodInvoke.class.getMethods();
+ for (Method m : methodArray) {
+ if (m.getName().equals(methodName)) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ @Benchmark
+ public void invokeWithoutParams() throws InvocationTargetException, IllegalAccessException {
+ staticMeth_0.invoke(null, args_0);
+ }
+
+ @Benchmark
+ public void invokeWithSixObjectParams() throws Exception {
+ staticMeth_6ref.invoke(null, args_6ref);
+ }
+
+ @Benchmark
+ public void invokeWithSixPrimitiveParams() throws Exception {
+ staticMeth_6prim.invoke(null, args_6prim);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/math/BigDecimals.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.math;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.math.BigDecimal;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class BigDecimals {
+
+ /** Make sure TEST_SIZE is used to size the arrays. We need this constant to parametrize the operations count. */
+ private static final int TEST_SIZE = 100;
+
+ /* dummy variables for intermediate results */
+ public Object[] dummyArr;
+ public String[] dummyStringArray;
+ public int dummy;
+
+ /* array to hold the created objects. */
+ private BigDecimal[] bigDecimals;
+ private String[] stringInputs;
+ private double[] doubleInputs;
+ private BigDecimal[] hugeArray, largeArray, smallArray;
+
+ @Setup
+ public void setup() {
+ Random r = new Random(1123);
+ dummyArr = new Object[TEST_SIZE];
+ bigDecimals = new BigDecimal[TEST_SIZE];
+ stringInputs = new String[TEST_SIZE];
+ doubleInputs = new double[TEST_SIZE];
+ for (int i = 0; i < TEST_SIZE; i++) {
+ double value = (double) (i + 1);
+ switch (i % 4) {
+ case 0:
+ value = -value * 54345.0d;
+ break;
+ case 1:
+ value = value * 5434543453454355e100;
+ break;
+ case 2:
+ value = -value / 5434543453454355e100;
+ break;
+ case 3:
+ break;
+ }
+
+ bigDecimals[i] = new BigDecimal(value);
+ stringInputs[i] = "" + value;
+ doubleInputs[i] = value;
+ }
+
+ /*
+ * Huge numbers larger than MAX_LONG
+ */
+ hugeArray = new BigDecimal[TEST_SIZE];
+
+ /*
+ * Large numbers less than MAX_LONG but larger than MAX_INT
+ */
+ largeArray = new BigDecimal[TEST_SIZE];
+
+ /*
+ * Small number less than MAX_INT
+ */
+ smallArray = new BigDecimal[TEST_SIZE];
+
+ dummyStringArray = new String[TEST_SIZE];
+ for (int i = 0; i < TEST_SIZE; i++) {
+ int value = Math.abs(r.nextInt());
+ hugeArray[i] = new BigDecimal("" + ((long) value + (long) Integer.MAX_VALUE)
+ + ((long) value + (long) Integer.MAX_VALUE) + ".55");
+ largeArray[i] = new BigDecimal("" + ((long) value + (long) Integer.MAX_VALUE) + ".55");
+ smallArray[i] = new BigDecimal("" + ((long) value / 1000) + ".55");
+ }
+ }
+
+ /** Invokes the (String)-constructor of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testConstructorWithString(Blackhole bh) {
+ for (String s : stringInputs) {
+ bh.consume(new BigDecimal(s));
+ }
+ }
+
+ /** Invokes the (double)-constructor of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testConstructorWithDouble(Blackhole bh) {
+ for (double s : doubleInputs) {
+ bh.consume(new BigDecimal(s));
+ }
+ }
+
+ /** Invokes the toString method of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testToString(Blackhole bh) {
+ for (BigDecimal s : bigDecimals) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /**
+ * Invokes the setScale method of BigDecimal with various different values.
+ */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testSetScale(Blackhole bh) {
+ for (BigDecimal s : bigDecimals) {
+ bh.consume(s.setScale(2, BigDecimal.ROUND_HALF_UP));
+ }
+ }
+
+ /** Invokes the setScale method of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(50 * TEST_SIZE)
+ public void testSetScaleVarious(Blackhole bh) {
+ for (int scale = 0; scale < 50; scale++) {
+ for (BigDecimal s : bigDecimals) {
+ bh.consume(s.setScale(scale, BigDecimal.ROUND_HALF_UP));
+ }
+ }
+ }
+
+ /** Invokes the add method of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testAdd(Blackhole bh) {
+ BigDecimal tmp = null;
+ for (BigDecimal s : bigDecimals) {
+ if (tmp == null) {
+ tmp = s;
+ continue;
+ }
+ tmp = tmp.add(s);
+ }
+ bh.consume(tmp);
+ }
+
+ /** Invokes the multiply method of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testMultiply(Blackhole bh) {
+ BigDecimal tmp = null;
+ for (BigDecimal s : bigDecimals) {
+ if (tmp == null) {
+ tmp = s;
+ continue;
+ }
+ tmp = tmp.multiply(s);
+ }
+ bh.consume(tmp);
+ }
+
+ /** Invokes the compareTo method of BigDecimal with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE - 1)
+ public void testCompareTo(Blackhole bh) {
+ BigDecimal c = bigDecimals[0];
+ for (BigDecimal s : bigDecimals) {
+ bh.consume(c.compareTo(s));
+ }
+ }
+
+ /** Test BigDecimal.toString() with huge numbers larger than MAX_LONG */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testHugeToString(Blackhole bh) {
+ for (BigDecimal s : hugeArray) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /** Test BigDecimal.toString() with large numbers less than MAX_LONG but larger than MAX_INT */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testLargeToString(Blackhole bh) {
+ for (BigDecimal s : largeArray) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /** Test BigDecimal.toString() with small numbers less than MAX_INT */
+ @Benchmark
+ @OperationsPerInvocation(TEST_SIZE)
+ public void testSmallToString(Blackhole bh) {
+ for (BigDecimal s : smallArray) {
+ bh.consume(s.toString());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/math/BigIntegers.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.openjdk.bench.java.math;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.math.BigInteger;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class BigIntegers {
+
+ private BigInteger[] hugeArray, largeArray, smallArray;
+ public String[] dummyStringArray;
+ public Object[] dummyArr;
+ private static final int TESTSIZE = 1000;
+
+ @Setup
+ public void setup() {
+ Random r = new Random(1123);
+
+ hugeArray = new BigInteger[TESTSIZE]; /*
+ * Huge numbers larger than
+ * MAX_LONG
+ */
+ largeArray = new BigInteger[TESTSIZE]; /*
+ * Large numbers less than
+ * MAX_LONG but larger than
+ * MAX_INT
+ */
+ smallArray = new BigInteger[TESTSIZE]; /*
+ * Small number less than
+ * MAX_INT
+ */
+
+ dummyStringArray = new String[TESTSIZE];
+ dummyArr = new Object[TESTSIZE];
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ int value = Math.abs(r.nextInt());
+
+ hugeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE)
+ + ((long) value + (long) Integer.MAX_VALUE));
+ largeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE));
+ smallArray[i] = new BigInteger("" + ((long) value / 1000));
+ }
+ }
+
+ /** Test BigInteger.toString() with huge numbers larger than MAX_LONG */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void testHugeToString(Blackhole bh) {
+ for (BigInteger s : hugeArray) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /** Test BigInteger.toString() with large numbers less than MAX_LONG but larger than MAX_INT */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void testLargeToString(Blackhole bh) {
+ for (BigInteger s : largeArray) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /** Test BigInteger.toString() with small numbers less than MAX_INT */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void testSmallToString(Blackhole bh) {
+ for (BigInteger s : smallArray) {
+ bh.consume(s.toString());
+ }
+ }
+
+ /** Invokes the multiply method of BigInteger with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void testMultiply(Blackhole bh) {
+ BigInteger tmp = null;
+ for (BigInteger s : hugeArray) {
+ if (tmp == null) {
+ tmp = s;
+ continue;
+ }
+ tmp = tmp.multiply(s);
+ }
+ bh.consume(tmp);
+ }
+
+ /** Invokes the multiply method of BigInteger with various different values. */
+ @Benchmark
+ @OperationsPerInvocation(TESTSIZE)
+ public void testAdd(Blackhole bh) {
+ BigInteger tmp = null;
+ for (BigInteger s : hugeArray) {
+ if (tmp == null) {
+ tmp = s;
+ continue;
+ }
+ tmp = tmp.add(s);
+ }
+ bh.consume(tmp);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/DatagramSocketTest.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.TearDown;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * DatagramSocket micros designed to stress UDP performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class DatagramSocketTest {
+
+ @Param({"1024", "2048", "4096", "8192", "16384", "32768"})
+ int size;
+
+ private DatagramSocket socket;
+ private DatagramPacket packet;
+
+ @Setup
+ public void prepare() throws SocketException, UnknownHostException {
+ socket = new DatagramSocket();
+
+ byte[] buf = new byte[size];
+ packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("localhost"), 9877);
+ }
+
+ @TearDown
+ public void cleanup() {
+ socket.close();
+ }
+
+ @Benchmark
+ public void testSend() throws IOException {
+ socket.send(packet);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketChannelReadWrite.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on network conditions and paltform.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketChannelReadWrite {
+
+ private ServerSocketChannel ssc;
+ private SocketChannel s1, s2;
+ private ReadThread rt;
+ private ByteBuffer bb = ByteBuffer.allocate(1);
+
+ @Setup(Level.Trial)
+ public void beforeRun() throws IOException {
+ InetAddress iaddr = InetAddress.getLocalHost();
+
+ ssc = ServerSocketChannel.open().bind(null);
+ s1 = SocketChannel.open(new InetSocketAddress(iaddr, ssc.socket().getLocalPort()));
+ s2 = ssc.accept();
+
+ rt = new ReadThread(s2);
+ rt.start();
+
+ bb.put((byte) 47);
+ bb.flip();
+ }
+
+ @TearDown(Level.Trial)
+ public void afterRun() throws IOException, InterruptedException {
+ s1.close();
+ s2.close();
+ ssc.close();
+ rt.join();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ s1.write(bb);
+ bb.flip();
+ }
+
+ static class ReadThread extends Thread {
+ private SocketChannel sc;
+
+ public ReadThread(SocketChannel s2) {
+ this.sc = s2;
+ }
+
+ public void run() {
+ try {
+ ByteBuffer bb = ByteBuffer.allocate(1);
+ while (sc.read(bb) > 0) {
+ bb.flip();
+ }
+ } catch (ClosedChannelException ex) {
+ // shutdown time
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketReadWrite.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on network conditions and paltform.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketReadWrite {
+
+ private OutputStream os;
+ private InputStream is;
+ private ServerSocket ss;
+ private Socket s1, s2;
+ private ReadThread rt;
+
+ @Setup
+ public void beforeRun() throws IOException {
+ InetAddress iaddr = InetAddress.getLocalHost();
+
+ ss = new ServerSocket(0);
+ s1 = new Socket(iaddr, ss.getLocalPort());
+ s2 = ss.accept();
+
+ os = s1.getOutputStream();
+ is = s2.getInputStream();
+
+ rt = new ReadThread(is);
+ rt.start();
+ }
+
+ @TearDown
+ public void afterRun() throws IOException, InterruptedException {
+ os.write(0);
+ os.close();
+ is.close();
+ s1.close();
+ s2.close();
+ ss.close();
+ rt.join();
+ }
+
+ @Benchmark
+ public void test() throws IOException {
+ os.write((byte) 4711);
+ }
+
+ static class ReadThread extends Thread {
+ private InputStream is;
+
+ public ReadThread(InputStream is) {
+ this.is = is;
+ }
+
+ public void run() {
+ try {
+ while (is.read() > 0);
+ } catch (SocketException ex) {
+ // ignore - most likely "socket closed", which means shutdown
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketStreaming.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Micro benchmark for streaming data over a Socket.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketStreaming {
+
+ /** The bytes to write/read. */
+ public static final int dataLength = 16383;
+ /** setTcpNoDelay(noNagle) */
+ public static final boolean noNagle = false;
+
+ private WriterThread writerThread;
+ private Socket readSocket;
+ private byte[] bytes;
+
+ @Setup
+ public void prepare() throws Exception {
+ bytes = new byte[dataLength];
+
+ // Setup the writer thread
+ writerThread = new WriterThread(dataLength, noNagle);
+ writerThread.start();
+
+ // Wait for a read socket
+ readSocket = writerThread.waitForReadSocket();
+ }
+
+ @TearDown
+ public void cleanup() throws IOException {
+ // Take down the writer thread and the reader socket
+ writerThread.finish();
+ while (!readSocket.isClosed()) {
+ readSocket.close();
+ }
+ readSocket = null;
+ }
+
+ @Benchmark
+ public void testSocketInputStreamRead() throws InterruptedException, IOException {
+ InputStream in = readSocket.getInputStream();
+
+ // Notify the writer thread to add elements to stream
+ writerThread.requestSendBytes();
+
+ // Read these from the stream
+ int bytesRead = 0;
+ while (bytesRead < dataLength) {
+ int lastRead = in.read(bytes);
+ if (lastRead < 0) {
+ throw new InternalError("Unexpectedly got " + lastRead + " bytes from the socket");
+ }
+ bytesRead += lastRead;
+ }
+ }
+
+ /**
+ * Thread used to write bytes to a socket.
+ */
+ private class WriterThread extends Thread {
+
+ /** The number of bytes to write. */
+ private int dataLength;
+ /** setTcpNoDelay(noNagle) */
+ private boolean noNagle;
+ /** Lock needed to send sendBytes requests. */
+ private final Object sendBytesLock = new Object();
+ /** Indicates that a sendBytes has been requested. */
+ private boolean sendBytesRequested;
+ /** Indicates that no more sendBytes will be requested. Time to shutdown. */
+ private boolean sendBytesDone;
+ /** Lock needed to protect the connectPort variable. */
+ private final Object connectLock = new Object();
+ /** The port the read socket should connect to. */
+ private int connectPort = -1;
+
+ /**
+ * Constructor.
+ *
+ * @param dataLength The number of bytes to write
+ * @param noNagle setTcpNoDelay(noNagle)
+ */
+ public WriterThread(int dataLength, boolean noNagle) {
+ super("Load producer");
+ this.dataLength = dataLength;
+ this.noNagle = noNagle;
+ }
+
+ /** Entry point for data sending helper thread. */
+ @Override
+ public void run() {
+ try {
+ Socket writeSocket;
+ ServerSocket serverSocket = new ServerSocket(0);
+
+ /* Tell the other thread that we now know the port number.
+ * The other thread will now start to connect until the following accept() call succeeds.
+ */
+ synchronized (connectLock) {
+ connectPort = serverSocket.getLocalPort();
+ connectLock.notify();
+ }
+
+ // Wait for the other thread to connect
+ writeSocket = serverSocket.accept();
+ writeSocket.setTcpNoDelay(noNagle);
+
+ // No more connects so this can be closed
+ serverSocket.close();
+ serverSocket = null;
+
+ OutputStream out = writeSocket.getOutputStream();
+
+ // Iterate as long as sendBytes are issued
+ while (waitForSendBytesRequest()) {
+ sendBytes(out);
+ }
+
+ // Time to shutdown
+ while (!writeSocket.isClosed()) {
+ writeSocket.close();
+ }
+ writeSocket = null;
+ } catch (Exception e) {
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Sends bytes to the output stream
+ *
+ * @param out The output stream
+ * @throws IOException
+ */
+ private void sendBytes(OutputStream out) throws IOException {
+ byte outBytes[] = new byte[dataLength];
+
+ int bytesToSend = dataLength;
+ int bytesSent = 0;
+ while (bytesSent < bytesToSend) {
+ out.write(outBytes);
+ bytesSent += outBytes.length;
+ }
+ }
+
+ /**
+ * Waits for the readSocket and returns it when it is ready.
+ *
+ * @return The socket to read from
+ * @throws InterruptedException
+ */
+ @SuppressWarnings("SleepWhileHoldingLock")
+ public Socket waitForReadSocket() throws InterruptedException {
+ int theConnectPort = waitForConnectPort();
+
+ while (true) {
+ try {
+ return new Socket(InetAddress.getByName(null), theConnectPort);
+ } catch (IOException e) {
+ // Wait some more for the server thread to get going
+ Thread.sleep(1000);
+ }
+ }
+
+ }
+
+ /**
+ * Waits for next sendBytes request
+ *
+ * @return <code>true</code> if it is time to sendBytes, <code>false</code> if it is time to shutdown
+ * @throws InterruptedException
+ */
+ public boolean waitForSendBytesRequest() throws InterruptedException {
+ synchronized (sendBytesLock) {
+ while (!sendBytesRequested && !sendBytesDone) {
+ sendBytesLock.wait();
+ }
+
+ // Clear the flag
+ sendBytesRequested = false;
+
+ return !sendBytesDone;
+ }
+ }
+
+ /** Requests a sendBytes. */
+ public void requestSendBytes() {
+ synchronized (sendBytesLock) {
+ sendBytesRequested = true;
+ sendBytesLock.notify();
+ }
+ }
+
+ /** Tells the writerThread that it is time to shutdown. */
+ public void finish() {
+ synchronized (sendBytesLock) {
+ sendBytesDone = true;
+ sendBytesLock.notify();
+ }
+ }
+
+ private int waitForConnectPort() throws InterruptedException {
+ synchronized (connectLock) {
+ while (connectPort == -1) {
+ connectLock.wait();
+ }
+ return connectPort;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.net.URLEncoder.encode and Decoder.decode.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class URLEncodeDecode {
+
+ @Param("1024")
+ public int count;
+
+ @Param("1024")
+ public int maxLength;
+
+ @Param("3")
+ public long mySeed;
+
+ public String[] testStringsEncode;
+ public String[] testStringsDecode;
+ public String[] toStrings;
+
+ @Setup
+ public void setupStrings() {
+ char[] tokens = new char[((int) 'Z' - (int) 'A' + 1) + ((int) 'z' - (int) 'a' + 1) + ((int) '9' - (int) '1' + 1) + 5];
+ int n = 0;
+ tokens[n++] = '0';
+ for (int i = (int) '1'; i <= (int) '9'; i++) {
+ tokens[n++] = (char) i;
+ }
+ for (int i = (int) 'A'; i <= (int) 'Z'; i++) {
+ tokens[n++] = (char) i;
+ }
+ for (int i = (int) 'a'; i <= (int) '<'; i++) {
+ tokens[n++] = (char) i;
+ }
+ tokens[n++] = '-';
+ tokens[n++] = '_';
+ tokens[n++] = '.';
+ tokens[n++] = '*';
+
+ Random r = new Random(mySeed);
+ testStringsEncode = new String[count];
+ testStringsDecode = new String[count];
+ toStrings = new String[count];
+ for (int i = 0; i < count; i++) {
+ int l = r.nextInt(maxLength);
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < l; j++) {
+ int c = r.nextInt(tokens.length);
+ sb.append(tokens[c]);
+ }
+ testStringsEncode[i] = sb.toString();
+ }
+
+ for (int i = 0; i < count; i++) {
+ int l = r.nextInt(maxLength);
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < l; j++) {
+ int c = r.nextInt(tokens.length + 5);
+ if (c >= tokens.length) {
+ sb.append("%").append(tokens[r.nextInt(16)]).append(tokens[r.nextInt(16)]);
+ } else {
+ sb.append(tokens[c]);
+ }
+ }
+ testStringsDecode[i] = sb.toString();
+ }
+ }
+
+ @Benchmark
+ public void testEncodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
+ for (String s : testStringsEncode) {
+ bh.consume(java.net.URLEncoder.encode(s, "UTF-8"));
+ }
+ }
+
+ @Benchmark
+ public void testDecodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
+ for (String s : testStringsDecode) {
+ bh.consume(URLDecoder.decode(s, "UTF-8"));
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.nio;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark operations on java.nio.Buffer.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ByteBuffers {
+
+ @Param({"10", "1000", "100000"})
+ private int size;
+
+ public byte dummyByte;
+ public char dummyChar;
+ public short dummyShort;
+ public int dummyInt;
+ public long dummyLong;
+ public float dummyFloat;
+ public double dummyDouble;
+
+ // ---------------- BULK GET TESTS
+
+ @Benchmark
+ public byte[] testBulkGet() {
+ return innerBufferBulkGet(ByteBuffer.allocate(size));
+ }
+
+ @Benchmark
+ public byte[] testDirectBulkGet() {
+ return innerBufferBulkGet(ByteBuffer.allocateDirect(size));
+ }
+
+ // ---------------- BULK PUT TESTS
+
+ @Benchmark
+ public byte[] testBulkPut() {
+ return innerBufferBulkPut(ByteBuffer.allocate(size));
+ }
+
+ @Benchmark
+ public byte[] testDirectBulkPut() {
+ return innerBufferBulkPut(ByteBuffer.allocateDirect(size));
+ }
+
+ // ---------------- SINGLE GET TESTS
+
+ @Benchmark
+ public int testSingleGetByte() {
+ return innerSingleGetByte(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public int testSingleGetChar() {
+ return innerSingleGetChar(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public int testSingleGetShort() {
+ return innerSingleGetShort(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public int testSingleGetInt() {
+ return innerSingleGetInt(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public long testSingleGetLong() {
+ return innerSingleGetLong(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public float testSingleGetFloat() {
+ return innerSingleGetFloat(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public double testSingleGetDouble() {
+ return innerSingleGetDouble(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public int testDirectSingleGetByte() {
+ return innerSingleGetByte(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public int testDirectSingleGetChar() {
+ return innerSingleGetChar(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public int testDirectSingleGetShort() {
+ return innerSingleGetShort(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public int testDirectSingleGetInt() {
+ return innerSingleGetInt(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public long testDirectSingleGetLong() {
+ return innerSingleGetLong(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public float testDirectSingleGetFloat() {
+ return innerSingleGetFloat(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public double testDirectSingleGetDouble() {
+ return innerSingleGetDouble(ByteBuffer.allocateDirect(1000));
+ }
+
+ // ---------------- SINGLE PUT TESTS
+
+ @Benchmark
+ public void testSinglePutByte() {
+ innerSinglePutByte(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutChar() {
+ innerSinglePutChar(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutShort() {
+ innerSinglePutShort(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutInt() {
+ innerSinglePutInt(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutLong() {
+ innerSinglePutLong(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutFloat() {
+ innerSinglePutFloat(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testSinglePutDouble() {
+ innerSinglePutDouble(ByteBuffer.allocate(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutByte() {
+ innerSinglePutByte(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutChar() {
+ innerSinglePutChar(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutShort() {
+ innerSinglePutShort(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutInt() {
+ innerSinglePutInt(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutLong() {
+ innerSinglePutLong(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutFloat() {
+ innerSinglePutFloat(ByteBuffer.allocateDirect(1000));
+ }
+
+ @Benchmark
+ public void testDirectSinglePutDouble() {
+ innerSinglePutDouble(ByteBuffer.allocateDirect(1000));
+ }
+
+ // ---------------- HELPER METHODS
+
+ private byte[] innerBufferBulkGet(ByteBuffer bb) {
+ byte[] dummyByteArray = new byte[bb.capacity()];
+ bb.get(dummyByteArray);
+ bb.flip();
+ return dummyByteArray;
+ }
+
+ private byte[] innerBufferBulkPut(ByteBuffer bb) {
+ byte[] dummyByteArray = new byte[bb.capacity()];
+ bb.put(dummyByteArray);
+ bb.flip();
+ return dummyByteArray;
+ }
+
+ private int innerSingleGetByte(ByteBuffer bb) {
+ int r = 0;
+ for (int i = 0; i < bb.capacity(); i++) {
+ r += bb.get(i);
+ }
+ return r;
+ }
+
+ private int innerSingleGetChar(ByteBuffer bb) {
+ int r = 0;
+ for (int i = 0; i < bb.capacity(); i += 2) {
+ r += bb.getChar(i);
+ }
+ return r;
+ }
+
+ private int innerSingleGetShort(ByteBuffer bb) {
+ int r = 0;
+ for (int i = 0; i < bb.capacity(); i += 2) {
+ r += bb.getShort(i);
+ }
+ return r;
+ }
+
+ private int innerSingleGetInt(ByteBuffer bb) {
+ int r = 0;
+ for (int i = 0; i < bb.capacity(); i += 4) {
+ r += bb.getInt(i);
+ }
+ return r;
+ }
+
+ private long innerSingleGetLong(ByteBuffer bb) {
+ long r = 0;
+ for (int i = 0; i < bb.capacity(); i += 8) {
+ r += bb.getLong(i);
+ }
+ return r;
+ }
+
+ private float innerSingleGetFloat(ByteBuffer bb) {
+ float r = 0;
+ for (int i = 0; i < bb.capacity(); i += 4) {
+ r += bb.getFloat(i);
+ }
+ return r;
+ }
+
+ private double innerSingleGetDouble(ByteBuffer bb) {
+ double d = 0;
+ for (int i = 0; i < bb.capacity(); i += 8) {
+ d += bb.getDouble(i);
+ }
+ return d;
+ }
+
+ private void innerSinglePutByte(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i++) {
+ bb.put(i, dummyByte);
+ }
+ }
+
+ private void innerSinglePutChar(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 2) {
+ bb.putChar(i, dummyChar);
+ }
+ }
+
+ private void innerSinglePutShort(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 2) {
+ bb.putShort(i, dummyShort);
+ }
+ }
+
+ private void innerSinglePutInt(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 4) {
+ bb.putInt(i, dummyInt);
+ }
+ }
+
+ private void innerSinglePutLong(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 8) {
+ bb.putLong(i, dummyLong);
+ }
+ }
+
+ private void innerSinglePutFloat(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 4) {
+ bb.putFloat(i, dummyFloat);
+ }
+ }
+
+ private void innerSinglePutDouble(ByteBuffer bb) {
+ for (int i = 0; i < bb.capacity(); i += 8) {
+ bb.putDouble(i, dummyDouble);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.nio;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark tests the encode/decode loops on different Charsets. It was created from an adhoc benchmark addressing
+ * a performance issue which in the end boiled down to the encode/decode loops. This is the reason for the values on the
+ * char and byte arrays.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class CharsetEncodeDecode {
+
+ private byte[] BYTES;
+ private char[] CHARS;
+
+ private CharsetEncoder encoder;
+ private CharsetDecoder decoder;
+
+ @Param({"BIG5", "ISO-8859-15", "ASCII", "UTF-16"})
+ private String type;
+
+ @Param("16384")
+ private int size;
+
+ @Setup
+ public void prepare() {
+ BYTES = new byte[size];
+ CHARS = new char[size];
+ for (int i = 0; i < size; ++i) {
+ int val = 48 + (i % 16);
+ BYTES[i] = (byte) val;
+ CHARS[i] = (char) val;
+ }
+
+ encoder = Charset.forName(type).newEncoder();
+ decoder = Charset.forName(type).newDecoder();
+ }
+
+ @Benchmark
+ public ByteBuffer encode() throws CharacterCodingException {
+ CharBuffer charBuffer = CharBuffer.wrap(CHARS);
+ return encoder.encode(charBuffer);
+ }
+
+ @Benchmark
+ public CharBuffer decode() throws CharacterCodingException {
+ ByteBuffer byteBuffer = ByteBuffer.wrap(BYTES);
+ return decoder.decode(byteBuffer);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/security/DoPrivileged.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.security;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring DoPrivileged
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class DoPrivileged {
+
+ private PrivilegedAction<Integer> privilegedAction;
+
+ @Setup
+ public void setup() {
+ privilegedAction = () -> 42;
+ }
+
+ @Benchmark
+ public int test() {
+ return AccessController.doPrivileged(privilegedAction);
+ }
+
+ @Benchmark
+ public int testInline() {
+ return AccessController.doPrivileged((PrivilegedAction<Integer>) () -> 42);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/security/MessageDigests.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.security;
+
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+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.Warmup;
+
+/**
+ * Tests various digester algorithms. Sets Fork parameters as these tests are
+ * rather allocation intensive. Reduced number of forks and iterations as
+ * benchmarks are stable.
+ */
+@State(Scope.Thread)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
+public class MessageDigests {
+
+ @Param({"64", "1024", "16384"})
+ private int length;
+
+ @Param({"md2", "md5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"})
+ private String digesterName;
+
+ @Param({"DEFAULT", "SUN"})
+ protected String provider;
+
+ private byte[] inputBytes;
+ private MessageDigest digester;
+
+ @Setup
+ public void setup() throws NoSuchAlgorithmException, DigestException, NoSuchProviderException {
+ inputBytes = new byte[length];
+ new Random(1234567890).nextBytes(inputBytes);
+ if ("DEFAULT".equals(provider)) {
+ digester = MessageDigest.getInstance(digesterName);
+ } else {
+ digester = MessageDigest.getInstance(digesterName, provider);
+ }
+ }
+
+ @Benchmark
+ public byte[] digest() throws DigestException {
+ return digester.digest(inputBytes);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/ArraysEquals.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for Array.equals() with 80 entry arrays differing at beginning, middle, or end.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArraysEquals {
+
+ public char[] testCharArray1 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".toCharArray();
+ public char[] testCharArray2 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789b".toCharArray();
+ public char[] testCharArray3 = "123456789012345678901234567890123456789a123456789012345678901234567890123456789b".toCharArray();
+ public char[] testCharArray4 = "1234567890a2345678901234567890123456789a123456789012345678901234567890123456789b".toCharArray();
+ public char[] testCharArray5 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".toCharArray();
+ public byte[] testByteArray1 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".getBytes();
+ public byte[] testByteArray2 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789b".getBytes();
+ public byte[] testByteArray3 = "123456789012345678901234567890123456789a123456789012345678901234567890123456789b".getBytes();
+ public byte[] testByteArray4 = "1234567890a2345678901234567890123456789a123456789012345678901234567890123456789b".getBytes();
+ public byte[] testByteArray5 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".getBytes();
+
+ /** Char array tests */
+
+ @Benchmark
+ public boolean testCharTrue() {
+ return Arrays.equals(testCharArray1, testCharArray5);
+ }
+
+ @Benchmark
+ public boolean testCharFalseEnd() {
+ return Arrays.equals(testCharArray1, testCharArray2);
+ }
+
+ @Benchmark
+ public boolean testCharFalseMid() {
+ return Arrays.equals(testCharArray1, testCharArray3);
+ }
+
+ @Benchmark
+ public boolean testCharFalseBeginning() {
+ return Arrays.equals(testCharArray1, testCharArray4);
+ }
+
+ /** Byte arrays tests */
+ @Benchmark
+ public boolean testByteTrue() {
+ return Arrays.equals(testByteArray1, testByteArray5);
+ }
+
+ @Benchmark
+ public boolean testByteFalseEnd() {
+ return Arrays.equals(testByteArray1, testByteArray2);
+ }
+
+ @Benchmark
+ public boolean testByteFalseMid() {
+ return Arrays.equals(testByteArray1, testByteArray3);
+ }
+
+ @Benchmark
+ public boolean testByteFalseBeginning() {
+ return Arrays.equals(testByteArray1, testByteArray4);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/Dates.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Dates {
+
+ int year = 75;
+ int month = 11;
+ int day = 23;
+ int hours = 16;
+ int minutes = 47;
+ int seconds = 12;
+
+ @Benchmark
+ public Date testEmptyConstructor() {
+ return new Date();
+ }
+
+ @SuppressWarnings("deprecation")
+ @Benchmark
+ public Date testIIIIIIConstructor() {
+ hours++;
+ minutes++;
+ seconds++;
+ return new Date(year, month, day, hours, minutes, seconds);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/GregorianCalendars.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class GregorianCalendars {
+
+ private Calendar calendar;
+ private long millis;
+
+ @Setup
+ public void setup() {
+ calendar = new GregorianCalendar();
+ millis = 4711L;
+ }
+
+ @Benchmark
+ public GregorianCalendar testConstructor() {
+ return new GregorianCalendar();
+ }
+
+ @Benchmark
+ public void testUpdate() {
+ calendar.setTimeInMillis(millis);
+ millis += 1L;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/RandomNext.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.util.Random's different flavours of next-methods.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class RandomNext {
+
+ public Random rnd;
+
+ @Setup
+ public void setup() {
+ rnd = new Random();
+ }
+
+ @Benchmark
+ public int testNextInt() {
+ return rnd.nextInt();
+ }
+
+ @Benchmark
+ public int testNextInt100() {
+ return rnd.nextInt(100);
+ }
+
+ @Benchmark
+ public int testNextInt128() {
+ return rnd.nextInt(128);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/ZipFind.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Tests ZipFile.getEntry() on the microbenchmarks.jar zip file
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ZipFind {
+
+ // Files that exist in the microbenchmarks.jar zip file
+ public static final String[] existingFiles = {"org/openjdk/bench/java/util/ZipFind.class",
+ "org/openjdk/bench/vm/lang/Throw.class",
+ "org/openjdk/bench/java/nio/ByteBuffers.class"};
+ public static String[] nonExistingFiles = {"/try/to/findme.not", "needle/in/a/HayStack.class"};
+
+ private ZipFile zip;
+
+ @Setup
+ public void prepare() throws IOException, URISyntaxException {
+ String zipFile = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
+ zip = new ZipFile(zipFile);
+
+ // Verify no typos in the filename lists above
+ assert zip.getEntry(ZipFind.nonExistingFiles[0]) == null;
+ assert zip.getEntry(ZipFind.existingFiles[0]) != null;
+ assert zip.getEntry(ZipFind.existingFiles[1]) != null;
+ assert zip.getEntry(ZipFind.existingFiles[2]) != null;
+ }
+
+ @TearDown
+ public void cleanup() throws IOException {
+ zip.close();
+ }
+
+ @Benchmark
+ public ZipEntry testOneNonExisting() throws IOException {
+ return zip.getEntry(ZipFind.nonExistingFiles[0]);
+ }
+
+ @Benchmark
+ public void testTwoNonExisting(Blackhole bh) throws IOException {
+ bh.consume(zip.getEntry(nonExistingFiles[0]));
+ bh.consume(zip.getEntry(nonExistingFiles[1]));
+ }
+
+ @Benchmark
+ public void testNonExistingAndExisting(Blackhole bh) throws IOException {
+ bh.consume(zip.getEntry(nonExistingFiles[0]));
+ bh.consume(zip.getEntry(existingFiles[0]));
+ }
+
+ @Benchmark
+ public ZipEntry testOneExisting() throws IOException {
+ return zip.getEntry(ZipFind.existingFiles[0]);
+ }
+
+ @Benchmark
+ public void testTwoExisting(Blackhole bh) throws IOException {
+ bh.consume(zip.getEntry(existingFiles[0]));
+ bh.consume(zip.getEntry(existingFiles[1]));
+ }
+
+ @Benchmark
+ public void testThreeExisting(Blackhole bh) throws IOException {
+ bh.consume(zip.getEntry(existingFiles[0]));
+ bh.consume(zip.getEntry(existingFiles[1]));
+ bh.consume(zip.getEntry(existingFiles[2]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Atomic {
+
+ public AtomicInteger aInteger;
+ public AtomicLong aLong;
+ public AtomicBoolean aBool;
+
+ public Object testObject1;
+ public Object testObject2;
+ public AtomicReference<Object> aReference;
+
+ /**
+ * The test variables are allocated every iteration so you can assume they are initialized to get similar behaviour
+ * across iterations
+ */
+ @Setup(Level.Iteration)
+ public void setupIteration() {
+ testObject1 = new Object();
+ testObject2 = new Object();
+ aInteger = new AtomicInteger(0);
+ aBool = new AtomicBoolean(false);
+ aReference = new AtomicReference<>(testObject1);
+ aLong = new AtomicLong(0);
+ }
+
+
+ /** Always swap in value. This test should be compiled into a CAS */
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void testAtomicIntegerAlways(Blackhole bh) {
+ bh.consume(aInteger.compareAndSet(0, 2));
+ bh.consume(aInteger.compareAndSet(2, 0));
+ }
+
+ /** Never write a value just return the old one. This test should be compiled into a CAS */
+ @Benchmark
+ public void testAtomicIntegerNever(Blackhole bh) {
+ bh.consume(aInteger.compareAndSet(1, 3));
+ }
+
+ /** Flips an atomic boolean on and off */
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void testAtomicBooleanFlip(Blackhole bh) {
+ bh.consume(aBool.getAndSet(true));
+ bh.consume(aBool.getAndSet(false));
+ }
+
+ /** Writes same value over and over */
+ @Benchmark
+ public void testAtomicBooleanSame(Blackhole bh) {
+ bh.consume(aBool.getAndSet(true));
+ }
+
+ /** Increment and get over multiple threads */
+ @Benchmark
+ public void testAtomicIntegerGetAndIncrement(Blackhole bh) {
+ bh.consume(aInteger.getAndIncrement());
+ }
+
+ /** Increment and get over multiple threads */
+ @Benchmark
+ public void testAtomicLongGetAndIncrement(Blackhole bh) {
+ bh.consume(aLong.getAndIncrement());
+ }
+
+ /** Swap a few references */
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void testAtomicReference(Blackhole bh) {
+ bh.consume(aReference.compareAndSet(testObject1, testObject2));
+ bh.consume(aReference.compareAndSet(testObject2, testObject1));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * Benchmarks assesses the performance of new Atomic* API.
+ *
+ * Implementation notes:
+ * - atomic instances are padded to eliminate false sharing
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class AtomicIntegerUpdateAndGet {
+
+ private PaddedAtomicInteger count;
+ private int value = 42;
+ private IntUnaryOperator captureOp;
+ private IntUnaryOperator noCaptureOp;
+
+ @Setup
+ public void setup() {
+ count = new PaddedAtomicInteger();
+ noCaptureOp = new IntUnaryOperator() {
+ public int applyAsInt(int v) {
+ return v + 42;
+ }
+ };
+ captureOp = new IntUnaryOperator() {
+ public int applyAsInt(int v) {
+ return v + value;
+ }
+ };
+ }
+
+ @Benchmark
+ public int testAddAndGet() {
+ return count.addAndGet(42);
+ }
+
+ @Benchmark
+ public int testInnerNoCapture() {
+ return count.updateAndGet(new IntUnaryOperator() {
+ public int applyAsInt(int v) {
+ return v + 42;
+ }
+ });
+ }
+
+ @Benchmark
+ public int testInnerCapture() {
+ return count.updateAndGet(new IntUnaryOperator() {
+ public int applyAsInt(int v) {
+ return v + value;
+ }
+ });
+ }
+
+ @Benchmark
+ public int testInnerCaptureCached() {
+ return count.updateAndGet(captureOp);
+ }
+
+ @Benchmark
+ public int testInnerNoCaptureCached() {
+ return count.updateAndGet(noCaptureOp);
+ }
+
+ @Benchmark
+ public int testLambdaNoCapture() {
+ return count.updateAndGet(x -> x + 42);
+ }
+
+ @Benchmark
+ public int testLambdaCapture() {
+ return count.updateAndGet(x -> x + value);
+ }
+
+ private static class PaddedAtomicInteger extends AtomicInteger {
+ private volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06, pad07;
+ private volatile long pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+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.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool forking infrastructure.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolForking {
+
+ /**
+ * Implementation notes:
+ *
+ * This test harnesses forking infrastructure within FJP.
+ * As such, no slack is given for allocating any humble number of tasks: the goal is to fork a lot.
+ * The approximate number of tasks is (SIZE / THRESHOLD).
+ *
+ * Raw baseline gives the idea for compute bound for this benchmark.
+ * FJP could be faster than baseline, because the baseline is single-threaded.
+ */
+
+ @Param("0")
+ private int workers;
+
+ @Param("10000000")
+ private int size;
+
+ @Param("10")
+ private int threshold;
+
+ private Problem problem;
+ private ForkJoinPool fjpSync;
+ private ForkJoinPool fjpAsync;
+
+ @Setup
+ public void setup() {
+ problem = new Problem(size);
+ if (workers == 0) {
+ workers = Runtime.getRuntime().availableProcessors();
+ }
+ fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);
+ fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
+ }
+
+ @TearDown
+ public void teardown() {
+ fjpSync.shutdownNow();
+ fjpAsync.shutdownNow();
+ }
+
+ @Benchmark
+ public long baselineRaw() {
+ return problem.solve();
+ }
+
+ @Benchmark
+ public Long testExplicit_Sync() throws ExecutionException, InterruptedException {
+ return fjpSync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold));
+ }
+
+ @Benchmark
+ public Long testExplicit_Async() throws ExecutionException, InterruptedException {
+ return fjpAsync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold));
+ }
+
+ @Benchmark
+ public Long testStandard_Sync() throws ExecutionException, InterruptedException {
+ return fjpSync.invoke(new StandardTask(problem, 0, problem.size(), threshold));
+ }
+
+ @Benchmark
+ public Long testStandard_Async() throws ExecutionException, InterruptedException {
+ return fjpAsync.invoke(new StandardTask(problem, 0, problem.size(), threshold));
+ }
+
+ private static class ExplicitTask extends RecursiveTask<Long> {
+ private final Problem problem;
+ private final int l;
+ private final int r;
+ private final int thresh;
+
+ public ExplicitTask(Problem p, int l, int r, int thresh) {
+ this.problem = p;
+ this.l = l;
+ this.r = r;
+ this.thresh = thresh;
+ }
+
+ @Override
+ protected Long compute() {
+ if (r - l <= thresh) {
+ return problem.solve(l, r);
+ }
+
+ int mid = (l + r) >>> 1;
+ ForkJoinTask<Long> t1 = new ExplicitTask(problem, l, mid, thresh);
+ ForkJoinTask<Long> t2 = new ExplicitTask(problem, mid, r, thresh);
+
+ t1.fork();
+ t2.fork();
+
+ long res = 0;
+ res += t2.join();
+ res += t1.join();
+ return res;
+ }
+ }
+
+ private static class StandardTask extends RecursiveTask<Long> {
+ private final Problem problem;
+ private final int l;
+ private final int r;
+ private final int thresh;
+
+ public StandardTask(Problem p, int l, int r, int thresh) {
+ this.problem = p;
+ this.l = l;
+ this.r = r;
+ this.thresh = thresh;
+ }
+
+ @Override
+ protected Long compute() {
+ if (r - l <= thresh) {
+ return problem.solve(l, r);
+ }
+
+ int mid = (l + r) >>> 1;
+ ForkJoinTask<Long> t1 = new StandardTask(problem, l, mid, thresh);
+ ForkJoinTask<Long> t2 = new StandardTask(problem, mid, r, thresh);
+
+ ForkJoinTask.invokeAll(t1, t2);
+ long res = 0;
+ res += t1.join();
+ res += t2.join();
+ return res;
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+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.TearDown;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses general ForkJoinPool performance with simple tasks
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class ForkJoinPoolRawCallable {
+
+ /**
+ * Implementation notes:
+ *
+ * This test submits empty callables.
+ * Callables are submitted in batches, to prevent convoying by driver threads.
+ * One driver thread can saturate up to BATCH_SIZE threads.
+ *
+ * One baseline includes raw throughput, without submissions to executors.
+ * This is not considered as fair comparison, but left around as basic compute baseline.
+ * Executors could not possibly be faster than that.
+ *
+ * Another baseline includes ThreadPoolExecutor.
+ * Note that this baseline is inherently non-scalable with ABQ backing TPE.
+ * The size of ABQ is chosen to accommodate tons of threads, which can also suffer due to cache effects.
+ *
+ * Tasks are reading public volatile field to break opportunistic optimizations in loops.
+ * Tasks are pre-allocated to negate instantiation costs.
+ */
+
+ @Param("0")
+ private int workers;
+
+ @Param("1000")
+ private int batchSize;
+
+ private ThreadPoolExecutor tpe;
+ private ForkJoinPool fjpSync;
+ private ForkJoinPool fjpAsync;
+ private List<SampleTask> tasks;
+
+ public volatile int arg = 42;
+
+ @Setup
+ public void setup() {
+ SampleTask task = new SampleTask();
+
+ tasks = new ArrayList<>();
+ for (int c = 0; c < batchSize; c++) {
+ tasks.add(task);
+ }
+
+ if (workers == 0) {
+ workers = Runtime.getRuntime().availableProcessors();
+ }
+
+ tpe = new ThreadPoolExecutor(workers, workers, 1, TimeUnit.HOURS, new ArrayBlockingQueue<>(batchSize * batchSize));
+ fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);
+ fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
+ }
+
+ @TearDown
+ public void teardown() {
+ tpe.shutdownNow();
+ fjpSync.shutdownNow();
+ fjpAsync.shutdownNow();
+ }
+
+ @Benchmark
+ public int baseline_raw() throws Exception {
+ int s = 0;
+ for (SampleTask t : tasks) {
+ s += t.call();
+ }
+ return s;
+ }
+
+ @Benchmark
+ public int baseline_TPE() throws Exception {
+ return doWork(tpe);
+ }
+
+ @Benchmark
+ public int testSync() throws ExecutionException, InterruptedException {
+ return doWork(fjpSync);
+ }
+
+ @Benchmark
+ public int testAsync() throws ExecutionException, InterruptedException {
+ return doWork(fjpAsync);
+ }
+
+ public int doWork(ExecutorService service) throws ExecutionException, InterruptedException {
+ List<Future<Integer>> futures = new ArrayList<>(tasks.size());
+ for (SampleTask task : tasks) {
+ futures.add(service.submit(task));
+ }
+
+ int s = 0;
+ for (Future<Integer> future : futures) {
+ s += future.get();
+ }
+ return s;
+ }
+
+ public class SampleTask implements Callable<Integer> {
+ @Override
+ public Integer call() throws Exception {
+ return arg;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+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.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdAutoQueued {
+
+ /**
+ * Implementation notes:
+ *
+ * This test solves the problem with threshold = 1, and adaptive heuristics. The optimal level is static,
+ * and lies somewhere in 1..2 interval. Note the test degrades significantly when heuristic starts to fail,
+ * and the throughput is buried under FJP overheads.
+ *
+ * Baseline includes solving problem sequentially. Hence, each test provides the speedup for parallel execution
+ * versus sequential version.
+ */
+
+ @Param("0")
+ private int workers;
+
+ @Param("10000000")
+ private int size;
+
+ @Param({"1", "2", "3", "4", "5", "6", "7", "8"})
+ private int threshold;
+
+ private ForkJoinPool fjp;
+ private Problem problem;
+
+ @Setup
+ public void setup() {
+ if (workers == 0) {
+ workers = Runtime.getRuntime().availableProcessors();
+ }
+
+ problem = new Problem(size);
+ fjp = new ForkJoinPool(workers);
+ }
+
+ @TearDown
+ public void teardown() {
+ fjp.shutdownNow();
+ }
+
+ @Benchmark
+ public long baselineRaw() {
+ return problem.solve();
+ }
+
+ @Benchmark
+ public Long test() throws ExecutionException, InterruptedException {
+ return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size()));
+ }
+
+ private static class AutoQueuedTask extends RecursiveTask<Long> {
+ private final int thr;
+ private final Problem problem;
+ private final int l;
+ private final int r;
+
+ public AutoQueuedTask(int thr, Problem p, int l, int r) {
+ this.thr = thr;
+ this.problem = p;
+ this.l = l;
+ this.r = r;
+ }
+
+ @Override
+ protected Long compute() {
+ if (r - l <= 1 || getQueuedTaskCount() >= thr) {
+ return problem.solve(l, r);
+ }
+
+ int mid = (l + r) >>> 1;
+ ForkJoinTask<Long> t1 = new AutoQueuedTask(thr, problem, l, mid);
+ ForkJoinTask<Long> t2 = new AutoQueuedTask(thr, problem, mid, r);
+
+ t2.fork();
+
+ long res = 0;
+ res += t1.invoke();
+ res += t2.join();
+ return res;
+ }
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+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.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdAutoSurplus {
+
+ /**
+ * Implementation notes:
+ *
+ * This test solves the problem with threshold = 1, and adaptive heuristics. The optimal level is static,
+ * and lies somewhere in 1..2 interval. Note the test degrades significantly when heuristic starts to fail,
+ * and the throughput is buried under FJP overheads.
+ *
+ * Baseline includes solving problem sequentially. Hence, each test provides the speedup for parallel execution
+ * versus sequential version.
+ */
+
+ @Param("0")
+ private int workers;
+
+ @Param("10000000")
+ private int size;
+
+ @Param({"1", "2", "3", "4", "5", "6", "7", "8"})
+ private int threshold;
+
+ private ForkJoinPool fjp;
+ private Problem problem;
+
+ @Setup
+ public void setup() {
+ if (workers == 0) {
+ workers = Runtime.getRuntime().availableProcessors();
+ }
+
+ problem = new Problem(size);
+ fjp = new ForkJoinPool(workers);
+ }
+
+ @TearDown
+ public void teardown() {
+ fjp.shutdownNow();
+ }
+
+ @Benchmark
+ public long baselineRaw() {
+ return problem.solve();
+ }
+
+ @Benchmark
+ public Long test() throws ExecutionException, InterruptedException {
+ return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size()));
+ }
+
+ private static class AutoQueuedTask extends RecursiveTask<Long> {
+ private final int thr;
+ private final Problem problem;
+ private final int l;
+ private final int r;
+
+ public AutoQueuedTask(int thr, Problem p, int l, int r) {
+ this.thr = thr;
+ this.problem = p;
+ this.l = l;
+ this.r = r;
+ }
+
+ @Override
+ protected Long compute() {
+ if (r - l <= 1 || getSurplusQueuedTaskCount() >= thr) {
+ return problem.solve(l, r);
+ }
+
+ int mid = (l + r) >>> 1;
+ ForkJoinTask<Long> t1 = new AutoQueuedTask(thr, problem, l, mid);
+ ForkJoinTask<Long> t2 = new AutoQueuedTask(thr, problem, mid, r);
+
+ t2.fork();
+
+ long res = 0;
+ res += t1.invoke();
+ res += t2.join();
+ return res;
+ }
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+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.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdStatic {
+
+ /**
+ * Implementation notes:
+ *
+ * This test solves the problem on different threshold levels.
+ * The optimal level depends on available parallelism.
+ * Lower thresholds will suffer because of ForkJoinPool infrastructure overheads.
+ * Higher thresholds will suffer because of lower available task parallelism.
+ *
+ * Baseline includes solving problem sequentially.
+ * Hence, each test provides the speedup for parallel execution
+ * versus sequential version.
+ */
+
+ @Param("0")
+ private int workers;
+
+ @Param("10000000")
+ private int size;
+
+ @Param({"1", "5", "10", "50", "100", "500", "1000", "5000", "10000", "50000", "100000", "500000", "1000000", "5000000", "10000000"})
+ private int threshold;
+
+ private ForkJoinPool fjp;
+ private Problem problem;
+
+ @Setup
+ public void setup() {
+ if (workers == 0) {
+ workers = Runtime.getRuntime().availableProcessors();
+ }
+
+ problem = new Problem(size);
+ fjp = new ForkJoinPool(workers);
+ }
+
+ @TearDown
+ public void teardown() {
+ fjp.shutdownNow();
+ }
+
+ @Benchmark
+ public long baselineRaw() {
+ return problem.solve();
+ }
+
+ @Benchmark
+ public Long test() throws ExecutionException, InterruptedException {
+ return fjp.invoke(new AdjustableThreshTask(threshold, problem, 0, problem.size()));
+ }
+
+ private static class AdjustableThreshTask extends RecursiveTask<Long> {
+ private final int thr;
+ private final Problem problem;
+ private final int l;
+ private final int r;
+
+ public AdjustableThreshTask(int thr, Problem p, int l, int r) {
+ this.thr = thr;
+ this.problem = p;
+ this.l = l;
+ this.r = r;
+ }
+
+ @Override
+ protected Long compute() {
+ if (r - l <= thr) {
+ return problem.solve(l, r);
+ }
+
+ int mid = (l + r) >>> 1;
+ ForkJoinTask<Long> t1 = new AdjustableThreshTask(thr, problem, l, mid);
+ ForkJoinTask<Long> t2 = new AdjustableThreshTask(thr, problem, mid, r);
+
+ ForkJoinTask.invokeAll(t1, t2);
+
+ long res = 0;
+ res += t1.join();
+ res += t2.join();
+ return res;
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Locks {
+
+ private ReentrantLock reentrantLock;
+ private ReentrantLock fairReentrantLock;
+ private ReentrantReadWriteLock reentrantRWLock;
+ private ReentrantReadWriteLock fairReentrantRWLock;
+ private Semaphore semaphore;
+ private Semaphore fairSemaphore;
+ private Lock reentrantWriteLock;
+ private Mutex mutex;
+
+ @Setup
+ public void setup() {
+ reentrantLock = new ReentrantLock(false);
+ fairReentrantLock = new ReentrantLock(true);
+ reentrantRWLock = new ReentrantReadWriteLock(false);
+ fairReentrantRWLock = new ReentrantReadWriteLock(true);
+ semaphore = new Semaphore(1, false);
+ fairSemaphore = new Semaphore(1, true);
+ reentrantWriteLock = new ReentrantReadWriteLock(false).writeLock();
+ mutex = new Mutex();
+ }
+
+ @Benchmark
+ public void testSynchronizedBlock() {
+ synchronized (this) {
+ Blackhole.consumeCPU(10);
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testFairReentrantLock() {
+ fairReentrantLock.lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ fairReentrantLock.unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testReentrantLock() {
+ reentrantLock.lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ reentrantLock.unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testFairReentrantReadWriteLock() {
+ fairReentrantRWLock.readLock().lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ fairReentrantRWLock.readLock().unlock();
+ }
+ fairReentrantRWLock.writeLock().lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ fairReentrantRWLock.writeLock().unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testReentrantReadWriteLock() {
+ reentrantRWLock.readLock().lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ reentrantRWLock.readLock().unlock();
+ }
+ reentrantRWLock.writeLock().lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ reentrantRWLock.writeLock().unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testReentrantWriteLock() {
+ reentrantWriteLock.lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ reentrantWriteLock.unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testFairSemaphore() throws InterruptedException {
+ fairSemaphore.acquire();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ fairSemaphore.release();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testSemaphore() throws InterruptedException {
+ semaphore.acquire();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ semaphore.release();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @Benchmark
+ public void testAbstractQueueSynchronizer() {
+ mutex.lock();
+ try {
+ Blackhole.consumeCPU(10);
+ } finally {
+ mutex.unlock();
+ }
+ Blackhole.consumeCPU(5);
+ }
+
+ @SuppressWarnings("serial")
+ private final class Mutex extends AbstractQueuedSynchronizer implements Lock, java.io.Serializable {
+
+ @Override
+ public boolean isHeldExclusively() {
+ return getState() == 1;
+ }
+
+ @Override
+ public boolean tryAcquire(int acquires) {
+ return compareAndSetState(0, 1);
+ }
+
+ @Override
+ public boolean tryRelease(int releases) {
+ setState(0);
+ return true;
+ }
+
+ @Override
+ public Condition newCondition() {
+ return new ConditionObject();
+ }
+
+ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ setState(0); // reset to unlocked state
+ }
+
+ @Override
+ public void lock() {
+ acquire(1);
+ }
+
+ @Override
+ public boolean tryLock() {
+ return tryAcquire(1);
+ }
+
+ @Override
+ public void lockInterruptibly() throws InterruptedException {
+ acquireInterruptibly(1);
+ }
+
+ @Override
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return tryAcquireNanos(1, unit.toNanos(timeout));
+ }
+
+ @Override
+ public void unlock() {
+ release(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+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 java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Maps {
+ private SimpleRandom rng;
+ private Map<Integer, Integer> map;
+ private Integer[] key;
+
+ private int removesPerMaxRandom;
+ private int insertsPerMaxRandom;
+ private int total;
+ private int position;
+
+ @Setup
+ public void initTest() {
+ int nkeys = 10000;
+ int pRemove = 10;
+ int pInsert = 90;
+ removesPerMaxRandom = (int) ((pRemove / 100.0 * 0x7FFFFFFFL));
+ insertsPerMaxRandom = (int) ((pInsert / 100.0 * 0x7FFFFFFFL));
+
+ rng = new SimpleRandom();
+ map = new ConcurrentHashMap<>();
+ total = 0;
+ key = new Integer[nkeys];
+ for (int i = 0; i < key.length; ++i) {
+ key[i] = new Integer(rng.next());
+ }
+ position = key.length / 2;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public void testConcurrentHashMap() {
+ int pos = position;
+ // random-walk around key positions, bunching accesses
+ int r = rng.next();
+ pos += (r & 7) - 3;
+ while (pos >= key.length) {
+ pos -= key.length;
+ }
+ while (pos < 0) {
+ pos += key.length;
+ }
+ Integer k = key[pos];
+ Integer x = map.get(k);
+ if (x != null) {
+ if (x.intValue() != k.intValue()) {
+ throw new Error("bad mapping: " + x + " to " + k);
+ }
+
+ if (r < removesPerMaxRandom) {
+ if (map.remove(k) != null) {
+ pos = total % key.length; // move from position
+ }
+ }
+ } else if (r < insertsPerMaxRandom) {
+ ++pos;
+ map.put(k, k);
+ }
+ total += r;
+ position = pos;
+ }
+
+ private static class SimpleRandom {
+ private final static long multiplier = 0x5DEECE66DL;
+ private final static long addend = 0xBL;
+ private final static long mask = (1L << 48) - 1;
+ private final static AtomicLong seq = new AtomicLong(1);
+ private long seed = System.nanoTime() + seq.getAndIncrement();
+
+ public int next() {
+ long nextSeed = (seed * multiplier + addend) & mask;
+ seed = nextSeed;
+ return ((int) (nextSeed >>> 17)) & 0x7FFFFFFF;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Problem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+
+/**
+ * Generic problem for concurrency tests.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+public class Problem {
+
+ /*
+ * Implementation notes:
+ *
+ * This problem makes its bidding to confuse loop unrolling and CSE, and as such break loop optimizations.
+ * Should loop optimizations be allowed, the performance with different (l, r) could change non-linearly.
+ */
+
+ private final int[] data;
+ private final int size;
+
+ public Problem(int size) {
+ this.size = size;
+ data = new int[size];
+ }
+
+ public long solve() {
+ return solve(0, size);
+ }
+
+ public long solve(int l, int r) {
+ long sum = 0;
+ for (int c = l; c < r; c++) {
+ int v = hash(data[c]);
+ if (filter(v)) {
+ sum += v;
+ }
+ }
+ return sum;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public static int hash(int x) {
+ x ^= (x << 21);
+ x ^= (x >>> 31);
+ x ^= (x << 4);
+ return x;
+ }
+
+ public static boolean filter(int i) {
+ return ((i & 0b101) == 0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests the different blocking queues in the java.util.concurrent package.
+ * The tests are done with a single producer and a variable number of consumers.
+ * The tests are created from Doug Lea's concurrent test suite.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class ProducerConsumer {
+
+ @Param("100")
+ private int capacity;
+
+ @Param
+ private QueueType type;
+
+ private BlockingQueue<Integer> q;
+ private Producer prod;
+
+ @Setup
+ public void prepare() {
+ switch (type) {
+ case ABQ_F:
+ q = new ArrayBlockingQueue<>(capacity, true);
+ break;
+ case ABQ_NF:
+ q = new ArrayBlockingQueue<>(capacity, false);
+ break;
+ case LBQ:
+ q = new LinkedBlockingQueue<>(capacity);
+ break;
+ case PBQ:
+ q = new PriorityBlockingQueue<>(capacity);
+ break;
+ default:
+ throw new RuntimeException();
+ }
+
+ prod = new Producer(q);
+ prod.start();
+ }
+
+ @TearDown
+ public void teardown() {
+ prod.halt();
+ }
+
+ @Benchmark
+ public void test() {
+ try {
+ int last = -1;
+ int v = q.take();
+ if (v < last) {
+ throw new Error("Out-of-Order transfer");
+ }
+ Blackhole.consumeCPU(10);
+ } catch (Exception ie) {
+ }
+ }
+
+ public enum QueueType {
+ LBQ,
+ ABQ_NF,
+ ABQ_F,
+ PBQ,
+ }
+
+ private class Producer extends Thread {
+ private final BlockingQueue<Integer> queue;
+ private int i = 0;
+ private volatile boolean running;
+
+ public Producer(BlockingQueue<Integer> queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ public void run() {
+ running = true;
+ try {
+ while (running) {
+ queue.put(i++);
+ }
+ } catch (Exception ie) {
+ }
+ }
+
+ public void halt() {
+ running = false;
+ this.interrupt();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Queues {
+
+ @Param("100")
+ private int capacity;
+
+ @Param
+ private QueueType type;
+
+ public enum QueueType {
+ LBQ,
+ ABQ_NF,
+ ABQ_F,
+ PBQ,
+ }
+
+ private BlockingQueue<Integer> q;
+
+ @Setup
+ public void setup() {
+ switch (type) {
+ case ABQ_F:
+ q = new ArrayBlockingQueue<>(capacity, true);
+ break;
+ case ABQ_NF:
+ q = new ArrayBlockingQueue<>(capacity, false);
+ break;
+ case LBQ:
+ q = new LinkedBlockingQueue<>(capacity);
+ break;
+ case PBQ:
+ q = new PriorityBlockingQueue<>(capacity);
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+
+ @Benchmark
+ public void test() {
+ try {
+ int l = (int) System.nanoTime();
+ Integer item = q.poll();
+ if (item != null) {
+ Blackhole.consumeCPU(5);
+ } else {
+ Blackhole.consumeCPU(10);
+ while (!q.offer(l)) {
+ Blackhole.consumeCPU(5);
+ }
+ }
+ } catch (Exception ie) {
+ throw new Error("iteration failed");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ThreadLocalRandomNextInt {
+
+ @State(Scope.Benchmark)
+ public static class Global {
+ public ThreadLocal<Random> tlr;
+ private List<ThreadLocal<Integer>> contaminators; // reachable, non-garbage-collectable
+
+ @Setup(Level.Trial)
+ public void setup() {
+ tlr = new ThreadLocal<Random>() {
+ @Override
+ protected Random initialValue() {
+ return java.util.concurrent.ThreadLocalRandom.current();
+ }
+ };
+
+ // contaminate ThreadLocals
+ int contaminatorCount = Integer.getInteger("contaminators", 0);
+ contaminators = new ArrayList<>(contaminatorCount);
+ for (int i = 0; i < contaminatorCount; i++) {
+ final int finalI = i;
+ ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return finalI;
+ }
+ };
+ contaminators.add(tl);
+ tl.get();
+ }
+ }
+ }
+
+ @State(Scope.Thread)
+ public static class Local {
+ public java.util.concurrent.ThreadLocalRandom tlr;
+
+ @Setup(Level.Trial)
+ public void setup() {
+ tlr = java.util.concurrent.ThreadLocalRandom.current();
+ }
+ }
+
+ @Benchmark
+ public int baseline(Local l) {
+ return l.tlr.nextInt();
+ }
+
+ @Benchmark
+ public int testJUC() {
+ return java.util.concurrent.ThreadLocalRandom.current().nextInt();
+ }
+
+ @Benchmark
+ public int testLang(Global g) {
+ return g.tlr.get().nextInt();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/logging/LogRecord.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.logging;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LogRecord {
+ private Logger logger;
+
+ @Setup
+ public void setup(final Blackhole bh) {
+ try {
+ logger = Logger.getLogger("logger");
+ logger.addHandler(new Handler() {
+ @Override
+ public void publish(java.util.logging.LogRecord record) {
+ bh.consume(record);
+ }
+
+ @Override
+ public void flush() {
+ // do nothing
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ // do nothing
+ }
+ });
+ logger.setLevel(Level.FINE);
+ logger.setUseParentHandlers(false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ @Benchmark
+ public void testFine() {
+ logger.log(Level.FINE, "test message");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/AllMatcher.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "allMatch" schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatcher {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - all operations have similar semantics
+ * - these use the qualifier duality: all(P(x)) === !(exists(!P(x))
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate op;
+
+ @Setup
+ public void setup() {
+ op = new LongPredicate() {
+ @Override
+ public boolean test(long x) {
+ return true;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_anyMatch() {
+ return LongStream.range(0, size).allMatch(op);
+ }
+
+ @Benchmark
+ public boolean seq_filter_findFirst() {
+ return !(LongStream.range(0, size).filter(op.negate()).findFirst().isPresent());
+ }
+
+ @Benchmark
+ public boolean seq_filter_findAny() {
+ return !(LongStream.range(0, size).filter(op.negate()).findAny().isPresent());
+ }
+
+ @Benchmark
+ public boolean par_anyMatch() {
+ return LongStream.range(0, size).parallel().allMatch(op);
+ }
+
+ @Benchmark
+ public boolean par_filter_findFirst() {
+ return !(LongStream.range(0, size).parallel().filter(op.negate()).findFirst().isPresent());
+ }
+
+ @Benchmark
+ public boolean par_filter_findAny() {
+ return !(LongStream.range(0, size).parallel().filter(op.negate()).findAny().isPresent());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/AnyMatcher.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "anyMatch" schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatcher {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - all operations have similar semantics
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate op;
+
+ @Setup
+ public void setup() {
+ op = new LongPredicate() {
+ @Override
+ public boolean test(long x) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_anyMatch() {
+ return LongStream.range(0, size).anyMatch(op);
+ }
+
+ @Benchmark
+ public boolean seq_filter_findFirst() {
+ return LongStream.range(0, size).filter(op).findFirst().isPresent();
+ }
+
+ @Benchmark
+ public boolean seq_filter_findAny() {
+ return LongStream.range(0, size).filter(op).findAny().isPresent();
+ }
+
+ @Benchmark
+ public boolean par_anyMatch() {
+ return LongStream.range(0, size).parallel().anyMatch(op);
+ }
+
+ @Benchmark
+ public boolean par_filter_findFirst() {
+ return LongStream.range(0, size).parallel().filter(op).findFirst().isPresent();
+ }
+
+ @Benchmark
+ public boolean par_filter_findAny() {
+ return LongStream.range(0, size).parallel().filter(op).findAny().isPresent();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/Decomposition.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+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 java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark is the golden benchmark for decompositions.
+ * There are at least four parameters to juggle:
+ * - pool parallelism (P), controlled via -Djava.util.concurrent.ForkJoinUtils.pool.parallelism
+ * - problem size (N), controlled as benchmark param
+ * - operation cost (Q), controlled as benchmark param
+ * - number of clients (C), controlled via -t option in harness
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Decomposition {
+
+ @Param("1000")
+ private int N;
+
+ @Param("1000")
+ private int Q;
+
+ @State(Scope.Thread)
+ public static class Thinktime {
+ @Param("10")
+ private int S;
+
+ @Setup(Level.Invocation)
+ public void sleep() throws InterruptedException {
+ TimeUnit.MILLISECONDS.sleep(S);
+ }
+ }
+
+ @Benchmark
+ public long saturated_sequential() throws InterruptedException {
+ return LongStream.range(1, N).filter(k -> doWork(k, Q)).sum();
+ }
+
+ @Benchmark
+ public long thinktime_sequential(Thinktime t) throws InterruptedException {
+ return LongStream.range(1, N).filter(k -> doWork(k, Q)).sum();
+ }
+
+ @Benchmark
+ public long saturated_parallel() throws InterruptedException {
+ return LongStream.range(1, N).parallel().filter(k -> doWork(k, Q)).sum();
+ }
+
+ @Benchmark
+ public long thinktime_parallel(Thinktime t) throws InterruptedException {
+ return LongStream.range(1, N).parallel().filter(k -> doWork(k, Q)).sum();
+ }
+
+ /**
+ * Make some work.
+ * This method have a couple of distinguishable properties:
+ * - the run time is linear with Q
+ * - the computation is dependent on input, preventing common reductions
+ * - the returned result is dependent on loop result, preventing dead code elimination
+ * - the returned result is almost always false
+ *
+ * This code uses inlined version of ThreadLocalRandom.next() to mitigate the edge effects
+ * of acquiring TLR every single call.
+ *
+ * @param input input
+ * @return result
+ */
+ public static boolean doWork(long input, long count) {
+ long t = input;
+ for (int i = 0; i < count; i++) {
+ t += (t * 0x5DEECE66DL + 0xBL) & (0xFFFFFFFFFFFFL);
+ }
+ return (t == 0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/NoneMatcher.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "noneMatch" schemes.
+ *
+ * @author Aleksey Shipilev, aleksey.shipilev@oracle.com
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatcher {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - all operations have similar semantics
+ * - these use the qualifier duality:
+ * exists(P(x)) === !all(!P(x)) =>
+ * !exists(P(x)) === all(!P(x))
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate op;
+
+ @Setup
+ public void setup() {
+ op = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_anyMatch() {
+ return LongStream.range(0, size).noneMatch(op);
+ }
+
+ @Benchmark
+ public boolean par_anyMatch() {
+ return LongStream.range(0, size).parallel().noneMatch(op);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/Reducers.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different reduce schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Reducers {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongBinaryOperator op;
+
+ @Setup
+ public void setup() {
+ op = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_reduce() {
+ return LongStream.range(0, size).reduce(op).getAsLong();
+ }
+
+ @Benchmark
+ public long par_reduce() {
+ return LongStream.range(0, size).parallel().reduce(op).getAsLong();
+ }
+
+ @Benchmark
+ public long seq_reduce_base() {
+ return LongStream.range(0, size).reduce(0L, op);
+ }
+
+ @Benchmark
+ public long par_reduce_base() {
+ return LongStream.range(0, size).parallel().reduce(0L, op);
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/LongAccumulator.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops;
+
+public class LongAccumulator {
+
+ long acc;
+
+ public LongAccumulator() {
+ acc = 0;
+ }
+
+ public void add(long v) {
+ acc += v;
+ }
+
+ public void merge(LongAccumulator other) {
+ acc += other.acc;
+ }
+
+ public long get() {
+ return acc;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always true to avert shortcurcuiting
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Predicate<Long> p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return true;
+ }
+ };
+ p2 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return true;
+ }
+ };
+ p3 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return true;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).boxed().allMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().allMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().allMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().allMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become false closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private Predicate<Long> pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v < offset;
+ }
+ };
+ pMid = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v < size / 2;
+ }
+ };
+ pEnd = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v < size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).boxed().allMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).boxed().allMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).boxed().allMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().boxed().allMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().boxed().allMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().boxed().allMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always false to avert shortcurcuiting
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Predicate<Long> p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ p2 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ p3 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).boxed().anyMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().anyMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().anyMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().anyMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become true closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private Predicate<Long> pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > offset;
+ }
+ };
+ pMid = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > size / 2;
+ }
+ };
+ pEnd = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).boxed().anyMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).boxed().anyMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).boxed().anyMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().boxed().anyMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().boxed().anyMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().boxed().anyMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Filter.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for filter() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Filter {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive predicates is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Predicate<Long> p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long l) {
+ return (l & 0b11111111) == 0;
+ }
+ };
+ p2 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long l) {
+ return (l & 0b00001111) == 0;
+ }
+ };
+ p3 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long l) {
+ return (l & 0x00000011) == 0;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .boxed()
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ return LongStream.range(0, size)
+ .boxed()
+ .filter(p1)
+ .filter(p1)
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .filter(p1)
+ .filter(p1)
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ return LongStream.range(0, size)
+ .boxed()
+ .filter(p1)
+ .filter(p2)
+ .filter(p3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .filter(p1)
+ .filter(p2)
+ .filter(p3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindAny.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findAny() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindAny {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public Long seq_invoke() {
+ return LongStream.range(0, size).boxed().findAny().get();
+ }
+
+ @Benchmark
+ public Long par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().findAny().get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindFirst.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findFirst() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindFirst {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public Long seq_invoke() {
+ return LongStream.range(0, size).boxed().findFirst().get();
+ }
+
+ @Benchmark
+ public Long par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().findFirst().get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/ForEach.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.Consumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach() operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ForEach {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongAdder sink;
+ private Consumer<Long> b1, b2, b3;
+
+ @Setup
+ public void setup() {
+ sink = new LongAdder();
+ b1 = new Consumer<Long>() {
+ @Override
+ public void accept(Long v) {
+ sink.add(v);
+ }
+ };
+ b2 = new Consumer<Long>() {
+ @Override
+ public void accept(Long v) {
+ sink.add(v);
+ }
+ };
+ b3 = new Consumer<Long>() {
+ @Override
+ public void accept(Long v) {
+ sink.add(v);
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ LongStream.range(0, size).boxed().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_chain111() {
+ LongStream.range(0, size).boxed().forEach(b1);
+ LongStream.range(0, size).boxed().forEach(b1);
+ LongStream.range(0, size).boxed().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_chain123() {
+ LongStream.range(0, size).boxed().forEach(b1);
+ LongStream.range(0, size).boxed().forEach(b2);
+ LongStream.range(0, size).boxed().forEach(b3);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ LongStream.range(0, size).parallel().boxed().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_chain111() {
+ LongStream.range(0, size).parallel().boxed().forEach(b1);
+ LongStream.range(0, size).parallel().boxed().forEach(b1);
+ LongStream.range(0, size).parallel().boxed().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_chain123() {
+ LongStream.range(0, size).parallel().boxed().forEach(b1);
+ LongStream.range(0, size).parallel().boxed().forEach(b2);
+ LongStream.range(0, size).parallel().boxed().forEach(b3);
+ return sink.sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Limit.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for limit() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Limit {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the tests include:
+ * - return nothing
+ * - return just a single element
+ * - return half
+ * - return all but last element
+ * - return all
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_baseline() {
+ return LongStream.range(0, size)
+ .boxed()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limit0() {
+ return LongStream.range(0, size)
+ .boxed()
+ .limit(0)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limit1() {
+ return LongStream.range(0, size)
+ .boxed()
+ .limit(1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitHalf() {
+ return LongStream.range(0, size)
+ .boxed()
+ .limit(size / 2)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitFull() {
+ return LongStream.range(0, size)
+ .boxed()
+ .limit(size - 1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitFullest() {
+ return LongStream.range(0, size)
+ .boxed()
+ .limit(size)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_baseline() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limit0() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .limit(0)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limit1() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .limit(1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitHalf() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .limit(size / 2)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitFull() {
+ return LongStream.range(0, size).parallel()
+ .boxed().limit(size - 1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitFullest() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .limit(size)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Map.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for map() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Map {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Function<Long, Long> m1, m2, m3;
+
+ @Setup
+ public void setup() {
+ m1 = new Function<Long, Long>() {
+ @Override
+ public Long apply(Long l) {
+ return l * 2;
+ }
+ };
+ m2 = new Function<Long, Long>() {
+ @Override
+ public Long apply(Long l) {
+ return l * 2;
+ }
+ };
+ m3 = new Function<Long, Long>() {
+ @Override
+ public Long apply(Long l) {
+ return l * 2;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .boxed()
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ return LongStream.range(0, size)
+ .boxed()
+ .map(m1)
+ .map(m1)
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .map(m1)
+ .map(m1)
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ return LongStream.range(0, size)
+ .boxed()
+ .map(m1)
+ .map(m2)
+ .map(m3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .map(m1)
+ .map(m2)
+ .map(m3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always false to avert shortcurcuiting
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Predicate<Long> p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ p2 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ p3 = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).boxed().noneMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).boxed().noneMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().noneMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().boxed().noneMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become true closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private Predicate<Long> pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > offset;
+ }
+ };
+ pMid = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > size / 2;
+ }
+ };
+ pEnd = new Predicate<Long>() {
+ @Override
+ public boolean test(Long v) {
+ return v > size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).boxed().noneMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).boxed().noneMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).boxed().noneMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().boxed().noneMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().boxed().noneMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().boxed().noneMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Reduce.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Reduce {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ */
+
+ @Param("100000")
+ private int size;
+
+ private BinaryOperator<Long> op1, op2, op3;
+
+ @Setup
+ public void setup() {
+ op1 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op2 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op3 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).boxed().reduce(op1).get();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).boxed().reduce(op1).get();
+ l += LongStream.range(0, size).boxed().reduce(op1).get();
+ l += LongStream.range(0, size).boxed().reduce(op1).get();
+ return l;
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).boxed().reduce(op1).get();
+ l += LongStream.range(0, size).boxed().reduce(op2).get();
+ l += LongStream.range(0, size).boxed().reduce(op3).get();
+ return l;
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+ l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+ l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+ return l;
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+ l += LongStream.range(0, size).parallel().boxed().reduce(op2).get();
+ l += LongStream.range(0, size).parallel().boxed().reduce(op3).get();
+ return l;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/ReduceBase.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce()-base operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ReduceBase {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private BinaryOperator<Long> op1, op2, op3;
+
+ @Setup
+ public void setup() {
+ op1 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op2 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op3 = new BinaryOperator<Long>() {
+ @Override
+ public Long apply(Long l, Long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).boxed().reduce(0L, op1);
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).boxed().reduce(0L, op1);
+ return l;
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).boxed().reduce(0L, op2);
+ l += LongStream.range(0, size).boxed().reduce(0L, op3);
+ return l;
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+ return l;
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op2);
+ l += LongStream.range(0, size).parallel().boxed().reduce(0L, op3);
+ return l;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Sorted.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for sorted() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Sorted {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - consecutive sorts should reuse the knowledge that stream was sorted already
+ */
+
+ @Param("100000")
+ private int size;
+
+ private Comparator<Long> cmp;
+
+ @Setup
+ public void setup() {
+ cmp = new Comparator<Long>() {
+ @Override
+ public int compare(Long x, Long y) {
+ return (x > y) ? 1 : (x < y ? -1 : 0);
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .boxed()
+ .sorted(cmp)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .sorted(cmp)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain() {
+ return LongStream.range(0, size)
+ .boxed()
+ .sorted(cmp)
+ .sorted(cmp)
+ .sorted(cmp)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .sorted(cmp)
+ .sorted(cmp)
+ .sorted(cmp)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/SortedUnique.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for both sorted() and uniq() operations.
+ * Sorts long range modulo power of two, then does unique elements.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class SortedUnique {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .boxed()
+ .mapToLong((l) -> l & 0xFFFF)
+ .sorted()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .mapToLong((l) -> l & 0xFFFF)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/UniqueElements.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for uniqueElements() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class UniqueElements {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .boxed()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain() {
+ return LongStream.range(0, size)
+ .boxed()
+ .distinct()
+ .distinct()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain() {
+ return LongStream.range(0, size).parallel()
+ .boxed()
+ .distinct()
+ .distinct()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always true to avert shortcurcuiting
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return true;
+ }
+ };
+ p2 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return true;
+ }
+ };
+ p3 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return true;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).allMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).allMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).allMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().allMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().allMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become false closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private LongPredicate pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v < offset;
+ }
+ };
+ pMid = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v < size / 2;
+ }
+ };
+ pEnd = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v < size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).allMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).allMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).allMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().allMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().allMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().allMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always false to avert shortcurcuiting
+ */
+ @Param("100000")
+ private int size;
+
+ private LongPredicate p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ p2 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ p3 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).anyMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).anyMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).anyMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().anyMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().anyMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become true closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private LongPredicate pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > offset;
+ }
+ };
+ pMid = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > size / 2;
+ }
+ };
+ pEnd = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).anyMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).anyMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).anyMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().anyMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().anyMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().anyMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Filter.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for filter() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Filter {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive predicates is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new LongPredicate() {
+ @Override
+ public boolean test(long l) {
+ return (l & 0b11111111) == 0;
+ }
+ };
+ p2 = new LongPredicate() {
+ @Override
+ public boolean test(long l) {
+ return (l & 0b00001111) == 0;
+ }
+ };
+ p3 = new LongPredicate() {
+ @Override
+ public boolean test(long l) {
+ return (l & 0x00000011) == 0;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ return LongStream.range(0, size)
+ .filter(p1)
+ .filter(p1)
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ return LongStream.range(0, size).parallel()
+ .filter(p1)
+ .filter(p1)
+ .filter(p1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ return LongStream.range(0, size)
+ .filter(p1)
+ .filter(p2)
+ .filter(p3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ return LongStream.range(0, size).parallel()
+ .filter(p1)
+ .filter(p2)
+ .filter(p3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/FindAny.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findAny() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindAny {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).findAny().getAsLong();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().findAny().getAsLong();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/FindFirst.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findFirst() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindFirst {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).findFirst().getAsLong();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().findFirst().getAsLong();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/ForEach.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongConsumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach() operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ForEach {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ */
+ @Param("100000")
+ private int size;
+
+ private LongConsumer b1, b2, b3;
+ private LongAdder sink;
+
+ @Setup
+ public void setup() {
+ sink = new LongAdder();
+ b1 = new LongConsumer() {
+ @Override
+ public void accept(long v) {
+ sink.add(v);
+ }
+ };
+ b2 = new LongConsumer() {
+ @Override
+ public void accept(long v) {
+ sink.add(v);
+ }
+ };
+ b3 = new LongConsumer() {
+ @Override
+ public void accept(long v) {
+ sink.add(v);
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ LongStream.range(0, size).forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_chain111() {
+ LongStream.range(0, size).forEach(b1);
+ LongStream.range(0, size).forEach(b1);
+ LongStream.range(0, size).forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_chain123() {
+ LongStream.range(0, size).forEach(b1);
+ LongStream.range(0, size).forEach(b2);
+ LongStream.range(0, size).forEach(b3);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ LongStream.range(0, size).parallel().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_chain111() {
+ LongStream.range(0, size).parallel().forEach(b1);
+ LongStream.range(0, size).parallel().forEach(b1);
+ LongStream.range(0, size).parallel().forEach(b1);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_chain123() {
+ LongStream.range(0, size).parallel().forEach(b1);
+ LongStream.range(0, size).parallel().forEach(b2);
+ LongStream.range(0, size).parallel().forEach(b3);
+ return sink.sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Limit.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for limit() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Limit {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the tests include:
+ * - return nothing
+ * - return just a single element
+ * - return half
+ * - return all but last element
+ * - return all
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_baseline() {
+ return LongStream.range(0, size)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limit0() {
+ return LongStream.range(0, size)
+ .limit(0)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limit1() {
+ return LongStream.range(0, size)
+ .limit(1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitHalf() {
+ return LongStream.range(0, size)
+ .limit(size / 2)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitFull() {
+ return LongStream.range(0, size)
+ .limit(size - 1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_limitFullest() {
+ return LongStream.range(0, size)
+ .limit(size)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_baseline() {
+ return LongStream.range(0, size).parallel()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limit0() {
+ return LongStream.range(0, size).parallel()
+ .limit(0)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limit1() {
+ return LongStream.range(0, size).parallel()
+ .limit(1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitHalf() {
+ return LongStream.range(0, size).parallel()
+ .limit(size / 2)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitFull() {
+ return LongStream.range(0, size).parallel()
+ .limit(size - 1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_limitFullest() {
+ return LongStream.range(0, size).parallel()
+ .limit(size)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Map.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongUnaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for map() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Map {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongUnaryOperator m1, m2, m3;
+
+ @Setup
+ public void setup() {
+ m1 = new LongUnaryOperator() {
+ @Override
+ public long applyAsLong(long l) {
+ return l * 2;
+ }
+ };
+ m2 = new LongUnaryOperator() {
+ @Override
+ public long applyAsLong(long l) {
+ return l * 2;
+ }
+ };
+ m3 = new LongUnaryOperator() {
+ @Override
+ public long applyAsLong(long l) {
+ return l * 2;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ return LongStream.range(0, size)
+ .map(m1)
+ .map(m1)
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ return LongStream.range(0, size).parallel()
+ .map(m1)
+ .map(m1)
+ .map(m1)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ return LongStream.range(0, size)
+ .map(m1)
+ .map(m2)
+ .map(m3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ return LongStream.range(0, size).parallel()
+ .map(m1)
+ .map(m2)
+ .map(m3)
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatch.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatch {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the predicates are always false to avert shortcurcuiting
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongPredicate p1, p2, p3;
+
+ @Setup
+ public void setup() {
+ p1 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ p2 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ p3 = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return false;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_invoke() {
+ return LongStream.range(0, size).noneMatch(p1);
+ }
+
+ @Benchmark
+ public int seq_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int seq_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).noneMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).noneMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public boolean par_invoke() {
+ return LongStream.range(0, size).parallel().noneMatch(p1);
+ }
+
+ @Benchmark
+ public int par_chain111() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+ return s;
+ }
+
+ @Benchmark
+ public int par_chain123() {
+ int s = 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p2)) ? 1 : 0;
+ s += (LongStream.range(0, size).parallel().noneMatch(p3)) ? 1 : 0;
+ return s;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatchShort.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatchShort {
+
+ /**
+ * Implementation notes:
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - test the predicate which will become true closer to start, in the middle, and closer to the end
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Param("100")
+ private int offset;
+
+ private LongPredicate pMid, pStart, pEnd;
+
+ @Setup
+ public void setup() {
+ pStart = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > offset;
+ }
+ };
+ pMid = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > size / 2;
+ }
+ };
+ pEnd = new LongPredicate() {
+ @Override
+ public boolean test(long v) {
+ return v > size - offset;
+ }
+ };
+ }
+
+ @Benchmark
+ public boolean seq_start() {
+ return LongStream.range(0, size).noneMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean seq_mid() {
+ return LongStream.range(0, size).noneMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean seq_end() {
+ return LongStream.range(0, size).noneMatch(pEnd);
+ }
+
+ @Benchmark
+ public boolean par_start() {
+ return LongStream.range(0, size).parallel().noneMatch(pStart);
+ }
+
+ @Benchmark
+ public boolean par_mid() {
+ return LongStream.range(0, size).parallel().noneMatch(pMid);
+ }
+
+ @Benchmark
+ public boolean par_end() {
+ return LongStream.range(0, size).parallel().noneMatch(pEnd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Reduce.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Reduce {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ */
+ @Param("100000")
+ private int size;
+
+ private LongBinaryOperator op1, op2, op3;
+
+ @Setup
+ public void setup() {
+ op1 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op2 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op3 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).reduce(op1).getAsLong();
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).reduce(op1).getAsLong();
+ l += LongStream.range(0, size).reduce(op1).getAsLong();
+ l += LongStream.range(0, size).reduce(op1).getAsLong();
+ return l;
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).reduce(op1).getAsLong();
+ l += LongStream.range(0, size).reduce(op2).getAsLong();
+ l += LongStream.range(0, size).reduce(op3).getAsLong();
+ return l;
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+ l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+ l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+ return l;
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+ l += LongStream.range(0, size).parallel().reduce(op2).getAsLong();
+ l += LongStream.range(0, size).parallel().reduce(op3).getAsLong();
+ return l;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/ReduceBase.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce()-base operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ReduceBase {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+ @Param("100000")
+ private int size;
+
+ private LongBinaryOperator op1, op2, op3;
+
+ @Setup
+ public void setup() {
+ op1 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op2 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ op3 = new LongBinaryOperator() {
+ @Override
+ public long applyAsLong(long l, long r) {
+ return (l > r) ? l : r;
+ }
+ };
+ }
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size).reduce(0L, op1);
+ }
+
+ @Benchmark
+ public long seq_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).reduce(0L, op1);
+ l += LongStream.range(0, size).reduce(0L, op1);
+ l += LongStream.range(0, size).reduce(0L, op1);
+ return l;
+ }
+
+ @Benchmark
+ public long seq_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).reduce(0L, op1);
+ l += LongStream.range(0, size).reduce(0L, op2);
+ l += LongStream.range(0, size).reduce(0L, op3);
+ return l;
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel().reduce(0L, op1);
+ }
+
+ @Benchmark
+ public long par_chain_111() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().reduce(0L, op1);
+ return l;
+ }
+
+ @Benchmark
+ public long par_chain_123() {
+ long l = 0;
+ l += LongStream.range(0, size).parallel().reduce(0L, op1);
+ l += LongStream.range(0, size).parallel().reduce(0L, op2);
+ l += LongStream.range(0, size).parallel().reduce(0L, op3);
+ return l;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Sorted.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for sorted() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Sorted {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - consecutive sorts should reuse the knowledge that stream was sorted already
+ */
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .sorted()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .sorted()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain() {
+ return LongStream.range(0, size).parallel()
+ .sorted()
+ .sorted()
+ .sorted()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain() {
+ return LongStream.range(0, size).parallel()
+ .sorted()
+ .sorted()
+ .sorted()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/SortedUnique.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for both sorted() and uniq() operations.
+ * Sorts long range modulo power of two, then does unique elements.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class SortedUnique {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ */
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(1, size)
+ .map(l -> l & 0xFFFF)
+ .sorted()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(1, size).parallel()
+ .map(l -> l & 0xFFFF)
+ .sorted()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/UniqueElements.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for uniqueElements() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class UniqueElements {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+ */
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long seq_invoke() {
+ return LongStream.range(0, size)
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_invoke() {
+ return LongStream.range(0, size).parallel()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long seq_chain() {
+ return LongStream.range(0, size)
+ .distinct()
+ .distinct()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+ @Benchmark
+ public long par_chain() {
+ return LongStream.range(0, size).parallel()
+ .distinct()
+ .distinct()
+ .distinct()
+ .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineParMultiple.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline fusion abilities.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class PipelineParMultiple {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public long bulk_into_anon() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> false)
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ @Benchmark
+ public long bulk_into_named() {
+ LongPredicate t = (x) -> true;
+ LongPredicate f = (x) -> false;
+ return LongStream.range(0, size).parallel()
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(f)
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+
+ @Benchmark
+ public long bulk_foreach_anon() {
+ LongAdder adder = new LongAdder();
+ LongStream.range(0, size).parallel().forEach((l) -> {
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> false).test(l))
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+
+ @Benchmark
+ public long bulk_foreach_named() {
+ LongAdder adder = new LongAdder();
+ LongPredicate t = (x) -> true;
+ LongPredicate f = (x) -> false;
+ LongStream.range(0, size).parallel().forEach((l) -> {
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (f.test(l))
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+ @Benchmark
+ public long bulk_ifs() {
+ LongAdder adder = new LongAdder();
+ LongStream.range(0, size).parallel().forEach((l) -> {
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (false)
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSeqMultiple.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline fusion abilities.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class PipelineSeqMultiple {
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public Object bulk_into_anon() {
+ return LongStream.range(0, size)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> true)
+ .filter((x) -> false)
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ @Benchmark
+ public Object bulk_into_named() {
+ LongPredicate t = (x) -> true;
+ LongPredicate f = (x) -> false;
+ return LongStream.range(0, size)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(t)
+ .filter(f)
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+
+ @Benchmark
+ public Object bulk_foreach_anon() {
+ LongAdder adder = new LongAdder();
+ LongStream.range(0, size).forEach((l) -> {
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> true).test(l))
+ if (((LongPredicate) (x) -> false).test(l))
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+
+ @Benchmark
+ public Object bulk_foreach_named() {
+ LongAdder adder = new LongAdder();
+ LongPredicate t = (x) -> true;
+ LongPredicate f = (x) -> false;
+ LongStream.range(0, size).forEach((l) -> {
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (t.test(l))
+ if (f.test(l))
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+ @Benchmark
+ public Object bulk_ifs() {
+ LongAdder adder = new LongAdder();
+ LongStream.range(0, size).forEach((l) -> {
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (true)
+ if (false)
+ adder.add(l);
+ });
+ return adder.sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSetup.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline construction costs.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class PipelineSetup {
+
+ /**
+ * This is one of the few benchmarks where measuring running time makes sense.
+ */
+
+ @Param("100000")
+ private int size;
+
+ @Benchmark
+ public Object baseline_newObject() {
+ return new Object();
+ }
+
+ @Benchmark
+ public LongStream seq_test00() {
+ return LongStream.range(0, size);
+ }
+
+ @Benchmark
+ public LongStream seq_test01() {
+ return LongStream.range(0, size)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream seq_test02() {
+ return LongStream.range(0, size)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream seq_test04() {
+ return LongStream.range(0, size)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream seq_test08() {
+ return LongStream.range(0, size)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream seq_test16() {
+ return LongStream.range(0, size)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream par_test00() {
+ return LongStream.range(0, size).parallel();
+ }
+
+ @Benchmark
+ public LongStream par_test01() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream par_test02() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream par_test04() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream par_test08() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+ @Benchmark
+ public LongStream par_test16() {
+ return LongStream.range(0, size).parallel()
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false)
+ .filter((x) -> false);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/Terminal.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongConsumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach()/iterator()/into() operations;
+ * Testing which one is faster for semantically-equvalent operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Terminal {
+
+ /**
+ * Implementation notes:
+ * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+ * - operations are explicit inner classes to untangle unwanted lambda effects
+ */
+
+ @Param("100000")
+ private int size;
+
+ private LongAdder sink;
+ private LongConsumer block;
+
+ @Setup
+ public void setup() {
+ sink = new LongAdder();
+ block = new LongConsumer() {
+ @Override
+ public void accept(long v) {
+ sink.add(v);
+ }
+ };
+ }
+
+ @Benchmark
+ public long baseline_prim_acc() {
+ long s = 0;
+ for (long l = 0L; l < size; l++) {
+ s += l;
+ }
+ sink.add(s);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long baseline_prim_sink() {
+ for (long l = 0L; l < size; l++) {
+ sink.add(l);
+ }
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long baseline_iterator_acc() {
+ long s = 0;
+ for (Iterator<Long> iterator = LongStream.range(0, size).boxed().iterator(); iterator.hasNext(); ) {
+ Long l = iterator.next();
+ s += l;
+ }
+ sink.add(s);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long baseline_iterator_sink() {
+ for (Iterator<Long> iterator = LongStream.range(0, size).boxed().iterator(); iterator.hasNext(); ) {
+ sink.add(iterator.next());
+ }
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_iterator() {
+ Iterator<Long> i = LongStream.range(0, size).boxed().iterator();
+ while (i.hasNext()) {
+ sink.add(i.next());
+ }
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_iterator() {
+ Iterator<Long> i = LongStream.range(0, size).parallel().boxed().iterator();
+ while (i.hasNext()) {
+ sink.add(i.next());
+ }
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_forEach() {
+ LongStream.range(1, size).forEach(block);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long par_forEach() {
+ LongStream.range(1, size).parallel().forEach(block);
+ return sink.sum();
+ }
+
+ @Benchmark
+ public long seq_into() {
+ return LongStream.range(1, size)
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ @Benchmark
+ public long par_into() {
+ return LongStream.range(1, size).parallel()
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DataProviders.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) , Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.stream.Stream;
+
+public class DataProviders {
+ public static Stream<String> dictionary() throws IOException {
+ BufferedReader r = new BufferedReader(new InputStreamReader(DataProviders.class.getResourceAsStream("cmudict-0.7b.txt")));
+ // Strip out the copyright notice and special chars
+ return r.lines().filter(w -> w.charAt(0) >= 'A' && w.charAt(0) <= 'Z').map(w -> w.substring(0, w.indexOf(" "))).onClose(() -> {
+ try {
+ r.close();
+ } catch (IOException e) {
+ // swallow
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ @Setup(Level.Trial)
+ public void loadData() {
+ // cause classload and problem initialization
+ DictionaryProblem.class.getName();
+ }
+
+ @Benchmark
+ public int hm_seq() {
+ int max = 0;
+ for (String s : DictionaryProblem.get()) {
+ int v = DictionaryProblem.wordValue(s);
+ if (v > max) {
+ max = v;
+ }
+ }
+ return max;
+ }
+
+ @Benchmark
+ public int hm_par() {
+ return new Task(DictionaryProblem.get(), 0, DictionaryProblem.get().length).invoke();
+ }
+
+ @Benchmark
+ public int bulk_seq_inner() {
+ return Arrays.stream(DictionaryProblem.get())
+ .map(new Function<String, Integer>() {
+ @Override
+ public Integer apply(String s) {
+ return DictionaryProblem.wordValue(s);
+ }
+ })
+ .reduce(0, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+ });
+ }
+
+ @Benchmark
+ public int bulk_par_inner() {
+ return Arrays.stream(DictionaryProblem.get()).parallel()
+ .map(new Function<String, Integer>() {
+ @Override
+ public Integer apply(String s) {
+ return DictionaryProblem.wordValue(s);
+ }
+ })
+ .reduce(0, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+ });
+ }
+
+
+ public static class Task extends RecursiveTask<Integer> {
+ private static final int FORK_LIMIT = 500;
+
+ private final String[] words;
+ private final int start, end;
+
+ Task(String[] w, int start, int end) {
+ this.words = w;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected Integer compute() {
+ int size = end - start;
+ if (size > FORK_LIMIT) {
+ int mid = start + size / 2;
+ Task t1 = new Task(words, start, mid);
+ Task t2 = new Task(words, mid, end);
+ t1.fork();
+ Integer v2 = t2.invoke();
+ Integer v1 = t1.join();
+ return Math.max(v1, v2);
+ } else {
+ int max = 0;
+ for (int i = start; i < end; i++) {
+ int v = DictionaryProblem.wordValue(words[i]);
+ if (v > max) {
+ max = v;
+ }
+ }
+ return max;
+ }
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/DictionaryProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.bench.java.util.stream.tasks.DataProviders;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class DictionaryProblem {
+
+ private static final int DICTIONARY_REPEAT_RATE = 40;
+
+ private static final String[] dict;
+
+ static {
+ int size;
+ int idx = 0;
+ List<String> d = Collections.emptyList();
+ try (Stream<String> s = DataProviders.dictionary()) {
+ d = s.collect(Collectors.<String>toList());
+ } catch (Exception e) {
+ // ignore
+ }
+ size = d.size() * DICTIONARY_REPEAT_RATE;
+ dict = new String[size];
+ for (int i = 0; i < DICTIONARY_REPEAT_RATE; i++) {
+ d.sort(new IdxComparator(i));
+ for (String s : d) {
+ // copy the whole string
+ dict[idx++] = new String(s.toCharArray());
+ }
+ }
+ assert (idx == dict.length);
+ }
+
+ public static String[] get() {
+ return dict;
+ }
+
+ /**
+ * A word value is the sum of alphabet value of each characters in a word.
+ *
+ * @param word The word
+ * @return The word value
+ */
+ public static int wordValue(String word) {
+ char[] ar = word.toLowerCase().toCharArray();
+ int value = 0;
+ for (char c: ar) {
+ int v = c - 'a' + 1;
+ if (v < 1 || v > 26) {
+ // skip non-alphabet
+ continue;
+ }
+ value += (c - 'a' + 1);
+ }
+ return value;
+ }
+
+ static class IdxComparator implements Comparator<String> {
+ private final int index;
+
+ public IdxComparator(int i) {
+ index = i;
+ }
+
+ @Override
+ public int compare(String a, String b) {
+ if (a.length() > index && b.length() > index) {
+ return (a.charAt(index) - b.charAt(index));
+ } else {
+ return (a.length() - b.length());
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+ @Setup(Level.Trial)
+ public void loadData() {
+ // cause classload and problem initialization
+ DictionaryProblem.class.getName();
+ }
+
+ public static Integer maxInt(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+
+ @Benchmark
+ public int bulk_seq_lambda() {
+ return Arrays.stream(DictionaryProblem.get())
+ .map(s -> DictionaryProblem.wordValue(s))
+ .reduce(0, (l, r) -> l > r ? l : r);
+ }
+
+ @Benchmark
+ public int bulk_seq_mref() {
+ return Arrays.stream(DictionaryProblem.get())
+ .map(DictionaryProblem::wordValue)
+ .reduce(0, Lambda::maxInt);
+ }
+
+ @Benchmark
+ public int bulk_par_lambda() {
+ return Arrays.stream(DictionaryProblem.get()).parallel()
+ .map(s -> DictionaryProblem.wordValue(s))
+ .reduce(0, (l, r) -> l > r ? l : r);
+ }
+
+ @Benchmark
+ public int bulk_par_mref() {
+ return Arrays.stream(DictionaryProblem.get()).parallel()
+ .map(DictionaryProblem::wordValue)
+ .reduce(0, Lambda::maxInt);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Xtras.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+public class Xtras {
+
+ // no workloads yet
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * This benchmark assesses flatMap() performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Bulk {
+
+ /**
+ * Implementation notes:
+ * - parallel versions need to use special sink to get the values
+ */
+
+ private IntegerDuplicateProblem problem;
+ private LongAdder adder;
+
+ @Setup
+ public void setup() {
+ problem = new IntegerDuplicateProblem();
+ adder = new LongAdder();
+ }
+
+ @Benchmark
+ public long hm_seq() {
+ for (Integer i : problem.get()) {
+ adder.add(i);
+ adder.add(i);
+ }
+ return adder.sum();
+ }
+
+ @Benchmark
+ public long hm_par() {
+ new Task(problem.get(), adder, 0, problem.get().length).invoke();
+ return adder.sum();
+ }
+
+ @Benchmark
+ public long bulk_seq_inner() {
+ return Arrays.stream(problem.get()).flatMap(new Function<Integer, Stream<Integer>>() {
+ @Override
+ public Stream<Integer> apply(Integer integer) {
+ return Collections.nCopies(2, integer).stream();
+ }
+ }).collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ @Benchmark
+ public long bulk_par_inner() {
+ return Arrays.stream(problem.get()).parallel().flatMap(new Function<Integer, Stream<Integer>>() {
+ @Override
+ public Stream<Integer> apply(Integer integer) {
+ return Collections.nCopies(2, integer).stream();
+ }
+ }).collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ public static class Task extends RecursiveAction {
+ private static final int FORK_LIMIT = 500;
+
+ private final Integer[] data;
+ private final LongAdder sink;
+ private final int start;
+ private final int end;
+
+ Task(Integer[] w, LongAdder sink, int start, int end) {
+ this.data = w;
+ this.sink = sink;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected void compute() {
+ int size = end - start;
+ if (size > FORK_LIMIT) {
+ int mid = start + size / 2;
+ Task t1 = new Task(data, sink, start, mid);
+ Task t2 = new Task(data, sink, mid, end);
+ t1.fork();
+ t2.invoke();
+ t1.join();
+ } else {
+ for (int i = start; i < end; i++) {
+ sink.add(i);
+ sink.add(i);
+ }
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/IntegerDuplicateProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import java.util.Random;
+
+public class IntegerDuplicateProblem {
+
+ private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+ private final Integer[] data = new Integer[DATA_SIZE];
+
+ public IntegerDuplicateProblem() {
+ // use fixed seed to reduce run-to-run variance
+ Random rand = new Random(0x30052012);
+
+ for (int i = 0; i < data.length; i++) {
+ data[i] = new Integer(rand.nextInt());
+ }
+ }
+
+ public Integer[] get() {
+ return data;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
+/**
+ * This benchmark assesses flatMap() performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Lambda {
+
+ /**
+ * Implementation notes:
+ * - parallel versions need to use special sink to get the values
+ */
+
+ private IntegerDuplicateProblem problem;
+
+ @Setup
+ public void setup() {
+ problem = new IntegerDuplicateProblem();
+ }
+
+ @Benchmark
+ public long lambda_seq_inner() {
+ return Arrays.stream(problem.get()).flatMap(k -> Collections.nCopies(2, k).stream())
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+ @Benchmark
+ public long lambda_par_inner() {
+ return Arrays.stream(problem.get()).parallel().flatMap(k -> Collections.nCopies(2, k).stream())
+ .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ private IntegerMaxProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new IntegerMaxProblem();
+ }
+
+ @Benchmark
+ public int hm_seq() {
+ int max = Integer.MIN_VALUE;
+ for (int v: problem.get()) {
+ if (v > max) {
+ max = v;
+ }
+ }
+ return max;
+ }
+
+ @Benchmark
+ public int hm_par() {
+ return new MaxIntTask(problem.get(), 0, problem.get().length).invoke();
+ }
+
+ @Benchmark
+ public int bulk_seq_inner() {
+ return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+ });
+ }
+
+ @Benchmark
+ public int bulk_par_inner() {
+ return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+ });
+ }
+
+ static class MaxIntTask extends RecursiveTask<Integer> {
+ private static final int FORK_LIMIT = 1000;
+ final Integer[] data;
+ final int start, end;
+
+ MaxIntTask(Integer[] data, int start, int end) {
+ this.data = data;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected Integer compute() {
+ int size = end - start;
+ if (size > FORK_LIMIT) {
+ int mid = start + size / 2;
+ MaxIntTask t1 = new MaxIntTask(data, start, mid);
+ MaxIntTask t2 = new MaxIntTask(data, mid, end);
+ t1.fork();
+ Integer v2 = t2.invoke();
+ Integer v1 = t1.join();
+ return Math.max(v1, v2);
+ } else {
+ int max = Integer.MIN_VALUE;
+ for (int i = start; i < end; i++) {
+ if (data[i] > max) {
+ max = data[i];
+ }
+ }
+ return max;
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/IntegerMaxProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import java.util.Random;
+
+public class IntegerMaxProblem {
+
+ private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+ private final Integer[] data = new Integer[DATA_SIZE];
+
+ public IntegerMaxProblem() {
+ // use fixed seed to reduce run-to-run variance
+ Random rand = new Random(0x30052012);
+
+ for (int i = 0; i < data.length; i++) {
+ data[i] = new Integer(rand.nextInt());
+ }
+ }
+
+ public Integer[] get() {
+ return data;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers lambda-specific solutions for the problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+ private IntegerMaxProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new IntegerMaxProblem();
+ }
+
+ public static Integer maxInt(Integer l, Integer r) {
+ return l > r ? l : r;
+ }
+
+ @Benchmark
+ public int bulk_seq_lambda() {
+ return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, (l, r) -> l > r ? l : r);
+ }
+
+ @Benchmark
+ public int bulk_seq_methodRef() {
+ return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, Lambda::maxInt);
+ }
+
+ @Benchmark
+ public int bulk_par_lambda() {
+ return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, (l, r) -> l > r ? l : r);
+ }
+
+ @Benchmark
+ public int bulk_par_methodRef() {
+ return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, Lambda::maxInt);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Xtras.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers other interesting solutions for the original problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Xtras {
+
+ private IntegerMaxProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new IntegerMaxProblem();
+ }
+
+
+// @Benchmark
+// public int bulk_seq_inner_pull() {
+// Stream<Integer> stream = Arrays.stream(problem.get());
+//
+// // force pull traversal
+// Integer car = stream.iterator().next();
+// Integer cdr = stream.reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+// @Override
+// public Integer apply(Integer l, Integer r) {
+// return l > r ? l : r;
+// }
+// });
+// return (car > cdr) ? car : cdr;
+// }
+//
+// @Benchmark
+// public int bulk_par_inner_pull() {
+// Stream<Integer> stream = Arrays.parallelStream(problem.get());
+//
+// // force pull traversal
+// Integer car = stream.iterator().next();
+// Integer cdr = stream.reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+// @Override
+// public Integer apply(Integer l, Integer r) {
+// return l > r ? l : r;
+// }
+// });
+// return (car > cdr) ? car : cdr;
+// }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ private IntegerSumProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new IntegerSumProblem();
+ }
+
+ @Benchmark
+ public int hm_seq() {
+ int sum = 0;
+ for (int v : problem.get()) {
+ sum += v;
+ }
+ return sum;
+ }
+
+ @Benchmark
+ public int hm_par() {
+ return new SumIntTask(problem.get()).invoke();
+ }
+
+ @Benchmark
+ public int bulk_seq_inner() {
+ return Arrays.stream(problem.get()).reduce(0, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer left, Integer right) {
+ return left + right;
+ }
+ });
+ }
+
+ @Benchmark
+ public int bulk_par_inner() {
+ return Arrays.stream(problem.get()).parallel().reduce(0, new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer left, Integer right) {
+ return left + right;
+ }
+ });
+ }
+
+ static class SumIntTask extends RecursiveTask<Integer> {
+ private static final int FORK_LIMIT = 1000;
+ final Integer[] data;
+ final int start, end;
+
+ SumIntTask(Integer[] data) {
+ this(data, 0, data.length);
+ }
+
+ SumIntTask(Integer[] data, int start, int end) {
+ this.data = data;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected Integer compute() {
+ int size = end - start;
+ if (size > FORK_LIMIT) {
+ int mid = start + size / 2;
+ SumIntTask t1 = new SumIntTask(data, start, mid);
+ SumIntTask t2 = new SumIntTask(data, mid, end);
+ t1.fork();
+ return t2.invoke() + t1.join();
+ } else {
+ int sum = 0;
+ for (int i = start; i < end; i++) {
+ sum += data[i];
+ }
+ return sum;
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/IntegerSumProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import java.util.Random;
+
+public class IntegerSumProblem {
+
+ private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+ private final Integer[] data = new Integer[DATA_SIZE];
+
+ public IntegerSumProblem() {
+ // use fixed seed to reduce run-to-run variance
+ Random rand = new Random(0x30052012);
+
+ for (int i = 0; i < data.length; i++) {
+ data[i] = new Integer(rand.nextInt());
+ }
+ }
+
+ public Integer[] get() {
+ return data;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers lambda-specific solutions for the problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+ private IntegerSumProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new IntegerSumProblem();
+ }
+
+ public static Integer sum(Integer a, Integer b) {
+ return a + b;
+ }
+
+ @Benchmark
+ public int bulk_seq_lambda() {
+ return Arrays.stream(problem.get()).reduce(0, (l, r) -> l + r);
+ }
+
+ @Benchmark
+ public int bulk_par_lambda() {
+ return Arrays.stream(problem.get()).parallel().reduce(0, (l, r) -> l + r);
+ }
+
+ @Benchmark
+ public int bulk_seq_mref() {
+ return Arrays.stream(problem.get()).reduce(0, Lambda::sum);
+ }
+
+ @Benchmark
+ public int bulk_par_mref() {
+ return Arrays.stream(problem.get()).parallel().reduce(0, Lambda::sum);
+ }
+
+ @Benchmark
+ public int bulk_seq_Integer_mref() {
+ return Arrays.stream(problem.get()).reduce(0, Integer::sum);
+ }
+
+ @Benchmark
+ public int bulk_par_Integer_mref() {
+ return Arrays.stream(problem.get()).parallel().reduce(0, Integer::sum);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Xtras.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers other interesting solutions for the original problem.
+ */
+public class Xtras {
+
+ // no workloads yet
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) , Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks.PhoneCode;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static org.openjdk.bench.java.util.stream.tasks.PhoneCode.PhoneCodeProblem.wordsForNumber;
+
+/**
+ * This benchmark compare various strategies solving the phone code problem.
+ * The result should offer some insights on strength/drawbacks of underlying
+ * implementation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class Bulk {
+ // several method choke up with 6-digit problem
+ private final static int SIZE = 5;
+ private Stream<String> join(String head,
+ String tail,
+ Function<String, Stream<String>> encoder)
+ {
+ Stream<String> s = wordsForNumber(head).stream();
+
+ if (! tail.isEmpty()) {
+ s = s.flatMap(h -> encoder.apply(tail).map(t -> h + " " + t));
+ }
+
+ return s;
+ }
+
+ private Stream<String> encode_par1(String number) {
+ return IntStream.range(1, number.length() + 1)
+ .parallel()
+ .boxed()
+ .flatMap(i -> join(number.substring(0, i),
+ number.substring(i),
+ this::encode_par1));
+ }
+
+ private Stream<String> encode_par2(String number) {
+ return IntStream.range(1, number.length() + 1)
+ .boxed()
+ .parallel()
+ .flatMap(i -> join(number.substring(0, i),
+ number.substring(i),
+ this::encode_par2));
+ }
+
+ private Stream<String> encode_ser(String number) {
+ return IntStream.range(1, number.length() + 1)
+ .boxed()
+ .flatMap(i -> join(number.substring(0, i),
+ number.substring(i),
+ this::encode_ser));
+ }
+
+ private Stream<String> encode_loop_concat(String number) {
+ if (number.isEmpty()) {
+ return Stream.empty();
+ }
+ // full number
+ Stream<String> s = wordsForNumber(number).stream();
+ // split
+ for (int i = 1; i < number.length(); i++) {
+ s = Stream.concat(s, join(number.substring(0, i),
+ number.substring(i),
+ this::encode_loop_concat));
+ }
+
+ return s;
+ }
+
+ private Collection<String> encode_loop_collect(String number) {
+ if (number.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ Collection<String> rv = new HashSet<>();
+
+ for (int i = 1; i <= number.length(); i++) {
+ join(number.substring(0, i),
+ number.substring(i),
+ s -> encode_loop_collect(s).stream()).forEach(rv::add);
+ }
+
+ return rv;
+ }
+
+ private Collection<String> encode_inline(String number) {
+ if (number.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ Collection<String> rv = new HashSet<>();
+
+ for (int i = 1; i < number.length(); i++) {
+ String front = number.substring(0, i);
+ String rest = number.substring(i);
+ wordsForNumber(front).stream()
+ .flatMap(h -> encode_inline(rest).stream().map(t -> h + " " + t))
+ .forEach(rv::add);
+ }
+
+ rv.addAll(wordsForNumber(number));
+
+ return rv;
+ }
+
+ @Benchmark
+ public int bulk_par_range_concurrent() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_par1)
+ .collect(Collectors.toConcurrentMap(
+ Function.identity(),
+ Function.identity(),
+ (l, r) -> l))
+ .keySet()
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_par_boxed_range_concurrent() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_par2)
+ .collect(Collectors.toConcurrentMap(
+ Function.identity(),
+ Function.identity(),
+ (l, r) -> l))
+ .keySet()
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_par_range() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_par1)
+ .collect(Collectors.toSet())
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_par_boxed_range() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_par2)
+ .collect(Collectors.toSet())
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_ser_range() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_ser)
+ .collect(Collectors.toSet())
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_ser_loop_concat() {
+ // force collect
+ return PhoneCodeProblem.get(SIZE)
+ .flatMap(this::encode_loop_concat)
+ .collect(Collectors.toSet())
+ .size();
+ }
+
+ @Benchmark
+ public int bulk_ser_loop_collect() {
+ return PhoneCodeProblem.get(SIZE)
+ .map(this::encode_loop_collect)
+ .map(Collection::size)
+ .reduce(0, Integer::sum);
+ }
+
+ @Benchmark
+ public int bulk_ser_inline() {
+ return PhoneCodeProblem.get(SIZE)
+ .map(this::encode_inline)
+ .map(Collection::size)
+ .reduce(0, Integer::sum);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/PhoneCodeProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks.PhoneCode;
+
+import org.openjdk.bench.java.util.stream.tasks.DataProviders;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The phone coder problem is trying to find full list of possible
+ * mnemonic combination of numbers.
+ *
+ * The solution is based on Martin Odersky's devoxx 2010 scala talk,
+ * where numbers are not allowed in the result, which is not really
+ * correct, but we don't care.
+ */
+public class PhoneCodeProblem {
+ // Map Character 'A'-'Z' to digits "2"-"9", key is charCode
+ private static final Map<Integer, String> CHAR_CODE;
+ // Map a string of digits to a collection of dictionary words
+ private static final Map<String, List<String>> WORD_CODES;
+
+ static {
+ HashMap<String, String> mnemonics = new HashMap<>(8);
+ mnemonics.put("2", "ABC");
+ mnemonics.put("3", "DEF");
+ mnemonics.put("4", "GHI");
+ mnemonics.put("5", "JKL");
+ mnemonics.put("6", "MNO");
+ mnemonics.put("7", "PQRS");
+ mnemonics.put("8", "TUV");
+ mnemonics.put("9", "WXYZ");
+
+ CHAR_CODE = new ConcurrentHashMap<>();
+ mnemonics.entrySet().stream().forEach(e ->
+ e.getValue().chars().forEach(c ->
+ { CHAR_CODE.put(c, e.getKey()); } ));
+
+ WORD_CODES = loadDictionary();
+ // System.out.println("Dictionary loaded with " + WORD_CODES.size() + " number entries");
+ }
+
+ // Convert a word to its number form
+ private static String wordToNumber(String word) {
+ return word.chars().mapToObj(CHAR_CODE::get)
+ .reduce("", String::concat);
+ }
+
+ // Prepare number -> word lookup table
+ private static Map<String, List<String>> loadDictionary() {
+ try (Stream<String> s = DataProviders.dictionary()) {
+ return s.filter(w -> w.length() > 1)
+ .filter(w -> w.matches("[a-zA-Z]*"))
+ .map(String::toUpperCase)
+ .collect(Collectors.groupingBy(PhoneCodeProblem::wordToNumber));
+ } catch (Exception ex) {
+ ex.printStackTrace(System.err);
+ return Collections.emptyMap();
+ }
+ }
+
+ public static Collection<String> wordsForNumber(String number) {
+ Collection<String> rv = WORD_CODES.get(number);
+ return (null == rv) ? Collections.emptySet() : rv;
+ }
+
+ public static Stream<String> get(int length) {
+ String digits[] = { "2", "3", "4", "5", "6", "7", "8", "9" };
+
+ Stream<String> s = Arrays.stream(digits);
+ for (int i = 1; i < length; i++) {
+ s = s.flatMap(d1 -> Arrays.stream(digits).map(d2 -> d1 + d2));
+ }
+ return s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/PrimesProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PrimesProblem {
+
+ /**
+ * Factors n into its prime factors. If n is prime,
+ * the result is a list of length 1 containing n.
+ *
+ * @param n the number to be factored
+ * @return a list of prime factors
+ */
+ static List<Long> factor(long n) {
+ List<Long> flist = new ArrayList<>();
+
+ while (n % 2L == 0) {
+ flist.add(2L);
+ n /= 2L;
+ }
+
+ long divisor = 3L;
+ while (n > 1L) {
+ long quotient = n / divisor;
+ if (n % divisor == 0) {
+ flist.add(divisor);
+ n = quotient;
+ } else if (quotient > divisor) {
+ divisor += 2L;
+ } else {
+ flist.add(n);
+ break;
+ }
+ }
+
+ return flist;
+ }
+
+ /**
+ * Tests whether n is prime.
+ *
+ * @param n the number to be tested
+ * @return true if n is prime, false if n is composite
+ */
+ public static boolean isPrime(long n) {
+ List<Long> factors = factor(n);
+ return (factors.size() == 1);
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ @Benchmark
+ public List<Long> hm_seq() {
+ List<Long> results = new ArrayList<>();
+ for (long i = RANGE_START; i < RANGE_END; i++) {
+ if (PrimesProblem.isPrime(i)) {
+ results.add(i);
+ }
+ }
+ return results;
+ }
+
+ @Benchmark
+ public List<Long> hm_par() {
+ return new FactoringTask(RANGE_START, RANGE_END).invoke();
+ }
+
+ @Benchmark
+ public List<Long> bulk_seq_inner() {
+ return LongStream.range(RANGE_START, RANGE_END)
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_inner() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel()
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_inner() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel()
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).sequential().collect(Collectors.<Long>toList());
+ }
+
+ public static class FactoringTask extends RecursiveTask<List<Long>> {
+ final long low;
+ final long high;
+
+ @Override
+ protected List<Long> compute() {
+ if (high - low == 1L) {
+ if (PrimesProblem.isPrime(low))
+ return Collections.singletonList(low);
+ else
+ return Collections.emptyList();
+ }
+
+ long mid = (low + high) / 2L;
+ FactoringTask t1 = new FactoringTask(low, mid);
+ FactoringTask t2 = new FactoringTask(mid, high);
+
+ List<Long> results;
+
+ // The right way to do it. Forks off one task and
+ // continues the other task in this thread. I've
+ // seen up to 8x speed up on 16-way Intel and 32-way
+ // SPARC boxes (which probably matches the actual number
+ // of cores they have, as opposed to the number of threads)
+ t2.fork();
+ results = new ArrayList<>(t1.compute());
+ results.addAll(t2.join());
+
+ return results;
+ }
+
+ FactoringTask(long low, long high) {
+ this.low = low;
+ this.high = high;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ @Benchmark
+ public List<Long> bulk_seq_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_seq_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).sequential().collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).sequential().collect(Collectors.<Long>toList());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Xtras.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+public class Xtras {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ /** No code yet **/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ @Benchmark
+ public List<Long> hm_seq() {
+ List<Long> results = new ArrayList<>();
+ for (long i = RANGE_START; i < RANGE_END; i++) {
+ if (PrimesProblem.isPrime(i)) {
+ results.add(i);
+ }
+ }
+ return results;
+ }
+
+ @Benchmark
+ public List<Long> hm_par() {
+ return new FactoringTask(RANGE_START, RANGE_END).invoke();
+ }
+
+ @Benchmark
+ public List<Long> bulk_seq_inner() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel()
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_inner() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel()
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_inner() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel()
+ .boxed()
+ .filter(new Predicate<Long>() {
+ @Override
+ public boolean test(Long o) {
+ return PrimesProblem.isPrime(o);
+ }
+ }
+ ).sequential().collect(Collectors.<Long>toList());
+ }
+
+ public static class FactoringTask extends RecursiveTask<List<Long>> {
+ final long low;
+ final long high;
+
+ @Override
+ protected List<Long> compute() {
+ if (high - low == 1L) {
+ if (PrimesProblem.isPrime(low))
+ return Collections.singletonList(low);
+ else
+ return Collections.emptyList();
+ }
+
+ long mid = (low + high) / 2L;
+ FactoringTask t1 = new FactoringTask(low, mid);
+ FactoringTask t2 = new FactoringTask(mid, high);
+
+ List<Long> results;
+
+ // The right way to do it. Forks off one task and
+ // continues the other task in this thread. I've
+ // seen up to 8x speed up on 16-way Intel and 32-way
+ // SPARC boxes (which probably matches the actual number
+ // of cores they have, as opposed to the number of threads)
+ t2.fork();
+ results = new ArrayList<>(t1.compute());
+ results.addAll(t2.join());
+
+ return results;
+ }
+
+ FactoringTask(long low, long high) {
+ this.low = low;
+ this.high = high;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Lambda.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ @Benchmark
+ public List<Long> bulk_seq_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_seq_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_par_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_lambda() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).sequential().collect(Collectors.<Long>toList());
+ }
+
+ @Benchmark
+ public List<Long> bulk_parseq_methodRef() {
+ return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).sequential().collect(Collectors.<Long>toList());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Xtras.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+public class Xtras {
+
+ private final long RANGE_START = 1000_000_000_000_000L;
+ private final long RANGE_END = RANGE_START + 100;
+
+ /** No code yet **/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/Bulk.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesSieve;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.function.Predicate;
+
+/**
+ * Bulk scenario: filter out candidate primes.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+ private PrimesSieveProblem problem;
+
+ @Setup(Level.Trial)
+ public void populateData(){
+ problem = new PrimesSieveProblem();
+ }
+
+ @Benchmark
+ public int hm_seq() {
+ int max = Integer.MIN_VALUE;
+ for (int d : problem.get()) {
+ if (PrimesSieveProblem.isNotDivisible(d, 2)
+ && PrimesSieveProblem.isNotDivisible(d, 3)
+ && PrimesSieveProblem.isNotDivisible(d, 5)
+ && PrimesSieveProblem.isNotDivisible(d, 7)
+ && PrimesSieveProblem.isNotDivisible(d, 11)
+ && PrimesSieveProblem.isNotDivisible(d, 13)
+ && PrimesSieveProblem.isNotDivisible(d, 17)
+ && PrimesSieveProblem.isNotDivisible(d, 19)
+ ) {
+ if (d > max) {
+ max = d;
+ }
+ }
+ }
+ return max;
+ }
+
+ @Benchmark
+ public int hm_par() {
+ return new FilterTask(problem.get()).invoke();
+ }
+
+ @Benchmark
+ public int bulk_seq_inner() {
+ return Arrays.stream(problem.get())
+ .filter(new FilterOp(2))
+ .filter(new FilterOp(3))
+ .filter(new FilterOp(5))
+ .filter(new FilterOp(7))
+ .filter(new FilterOp(11))
+ .filter(new FilterOp(13))
+ .filter(new FilterOp(17))
+ .filter(new FilterOp(19))
+ .reduce(Integer.MIN_VALUE, new ReduceOp());
+ }
+
+ @Benchmark
+ public int bulk_par_inner() {
+ return Arrays.stream(problem.get()).parallel()
+ .filter(new FilterOp(2))
+ .filter(new FilterOp(3))
+ .filter(new FilterOp(5))
+ .filter(new FilterOp(7))
+ .filter(new FilterOp(11))
+ .filter(new FilterOp(13))
+ .filter(new FilterOp(17))
+ .filter(new FilterOp(19))
+ .reduce(Integer.MIN_VALUE, new ReduceOp());
+ }
+
+ static class FilterOp implements Predicate<Integer> {
+ private final int divisor;
+
+ public FilterOp(int divisor) {
+ this.divisor = divisor;
+ }
+
+ @Override
+ public boolean test(Integer value) {
+ return PrimesSieveProblem.isNotDivisible(value, divisor);
+ }
+ }
+
+ static class ReduceOp implements BinaryOperator<Integer> {
+ @Override
+ public Integer apply(Integer left, Integer right) {
+ return (left > right) ? left : right;
+ }
+ }
+
+ static class FilterTask extends RecursiveTask<Integer> {
+ private static final int FORK_LIMIT = 1000;
+ final Integer[] data;
+ final int start, end;
+
+ FilterTask(Integer[] data) {
+ this(data, 0, data.length);
+ }
+
+ FilterTask(Integer[] data, int start, int end) {
+ this.data = data;
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected Integer compute() {
+ int size = end - start;
+ if (size > FORK_LIMIT) {
+ int mid = start + size / 2;
+ FilterTask t1 = new FilterTask(data, start, mid);
+ FilterTask t2 = new FilterTask(data, mid, end);
+ t1.fork();
+ Integer r1 = t2.invoke();
+ Integer r2 = t1.join();
+ return (r1 > r2) ? r1 : r2;
+ } else {
+ int max = Integer.MIN_VALUE;
+ for (int i = start; i < end; i++) {
+ int d = data[i];
+ if (PrimesSieveProblem.isNotDivisible(d, 2)
+ && PrimesSieveProblem.isNotDivisible(d, 3)
+ && PrimesSieveProblem.isNotDivisible(d, 5)
+ && PrimesSieveProblem.isNotDivisible(d, 7)
+ && PrimesSieveProblem.isNotDivisible(d, 11)
+ && PrimesSieveProblem.isNotDivisible(d, 13)
+ && PrimesSieveProblem.isNotDivisible(d, 17)
+ && PrimesSieveProblem.isNotDivisible(d, 19)
+ ) {
+ if (d > max) {
+ max = d;
+ }
+ }
+ }
+ return max;
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/PrimesSieveProblem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesSieve;
+
+public class PrimesSieveProblem {
+
+ private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024);
+
+ private final Integer[] data = new Integer[DATA_SIZE];
+
+ public PrimesSieveProblem() {
+ for (int i = 0; i < data.length; i++) {
+ data[i] = i;
+ }
+ }
+
+ public Integer[] get() {
+ return data;
+ }
+
+ public static boolean isNotDivisible(int i, int d) {
+ return (i % d) != 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/README Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,55 @@
+Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+
+=======================================================================
+
+The tests are divided by scenario.
+
+Each scenario has the problem it tries to solve, and it does that with several options:
+ - BulkBench only compares handmade solutions vs. JDK bulk operations, without resorting to lambdas/methodrefs
+ - LambdaBench does bulk operations with lambdas/methodrefs
+ - XtrasBench has some other interesting options
+
+All tests in these benchmarks follow the following naming convention.
+Test names is the concatenation of several markers:
+
+{hm|bulk}: infrastructure used
+ - hm: "handmade" version which users would presumably implement otherwise
+ - bulk: JDK8-ish bulk operation
+
+{seq|par}: parallelism mode
+ - seq: sequential mode
+ - par: parallel mode; in "hm" case, this might have different implementations
+
+{.|inner|lambda|mref}: functional interface type
+ - .: no specific meaning
+ - inner: explicit inner class
+ - lambda: JDK8-ish lambda
+ - mref: JDK8-ish method ref
+
+E.g. bulk_seq_inner is the test harnesses JDK8 bulk operations in sequential mode, and explicit inner class as function
+
+All benchmarks should be executed in the following modes (see -t harness cmdline option):
+ - single mode (thread = 1),
+ - core mode (thread = number of cores),
+ - max mode (thread = number of HW threads).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/AES.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto;
+
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Benchmark;
+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 javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AES {
+
+ @Param("10000000")
+ private int count;
+
+ private Cipher cipher;
+ private byte[] src;
+
+ @Setup
+ public void setup() throws Exception {
+ SecretKeySpec keySpec = new SecretKeySpec(new byte[]{-80, -103, -1, 68, -29, -94, 61, -52, 93, -59, -128, 105, 110, 88, 44, 105}, "AES");
+ IvParameterSpec iv = new IvParameterSpec(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+ cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+ src = new byte[count];
+ new Random(1).nextBytes(src);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:-UseAES", "-XX:-UseAESIntrinsics"})
+ public byte[] testBaseline() throws Exception {
+ return cipher.doFinal(src);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+UseAES", "-XX:-UseAESIntrinsics"})
+ public byte[] testUseAes() throws Exception {
+ return cipher.doFinal(src);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+UseAES", "-XX:+UseAESIntrinsics"})
+ public byte[] testUseAesIntrinsics() throws Exception {
+ return cipher.doFinal(src);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/Crypto.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+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.Warmup;
+
+/**
+ * Tests various encryption algorithms with the JCE framework. Sets Fork
+ * parameters as these tests are rather allocation intensive. Reduced numbers of
+ * forks and iteration as benchmarks are stable.
+ */
+@State(Scope.Thread)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
+public class Crypto {
+
+ @Param({"64", "1024", "16384"})
+ private int length;
+
+ @Param({"AES", "Blowfish", "DES", "DESede"})
+ private String cipherName;
+
+ private SecretKeySpec secretKey;
+ private Cipher encryptCipher;
+ private Cipher decryptCipher;
+ private byte[] plainBytes;
+ private byte[] encryptedBytes;
+
+ @Setup
+ public void setupSubclass() throws NoSuchAlgorithmException, NoSuchPaddingException,
+ InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+
+ // Setup ciphers for encrypt/decrypt
+ byte[] encodedKey = KeyGenerator.getInstance(cipherName).generateKey().getEncoded();
+ secretKey = new SecretKeySpec(encodedKey, cipherName);
+
+ encryptCipher = Cipher.getInstance(cipherName);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+ decryptCipher = Cipher.getInstance(cipherName);
+ decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
+
+ // Generate data to encrypt/decrypt
+ plainBytes = new byte[length];
+ new Random(1234567890).nextBytes(plainBytes);
+ encryptedBytes = encryptCipher.doFinal(plainBytes);
+ }
+
+ /**
+ * Encrypt byte array
+ *
+ * @return encrypted byte array
+ * @throws javax.crypto.IllegalBlockSizeException
+ * @throws javax.crypto.BadPaddingException
+ */
+ @Benchmark
+ public byte[] encrypt() throws IllegalBlockSizeException, BadPaddingException {
+ return encryptCipher.doFinal(plainBytes);
+ }
+
+ /**
+ * Decrypt byte array
+ *
+ * @return decrypted byte array
+ * @throws javax.crypto.IllegalBlockSizeException
+ * @throws javax.crypto.BadPaddingException
+ */
+ @Benchmark
+ public byte[] decrypt() throws IllegalBlockSizeException, BadPaddingException {
+ return decryptCipher.doFinal(encryptedBytes);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/tools/Javac.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.tools;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import javax.tools.JavaCompiler;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class Javac {
+ private List<JavaSourceFromString> compilationUnits;
+ private JavaCompiler compiler;
+ private StandardJavaFileManager fileManager;
+
+ @Setup
+ public void prepare() {
+ String helloWorld = "class Apan { \n" + " public static void main(String args[]) {\n"
+ + " System.out.println(\"hej apa\");\n" + " }\n" + "}\n";
+
+ compiler = ToolProvider.getSystemJavaCompiler();
+ fileManager = compiler.getStandardFileManager(null, null, null);
+ compilationUnits = new ArrayList<>();
+ compilationUnits.add(new JavaSourceFromString("Apan", helloWorld));
+ }
+
+ @Benchmark
+ public Boolean testCompile() throws Exception {
+ JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
+ return task.call();
+ }
+
+ private static class JavaSourceFromString extends SimpleJavaFileObject {
+ final String code;
+
+ JavaSourceFromString(String name, String code) {
+ super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
+ Kind.SOURCE);
+ this.code = code;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return code;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Abstract base class with functionality and constants used by the XML micros.
+ */
+@State(Scope.Benchmark)
+public abstract class AbstractXMLMicro {
+
+ public static final String BUILDIMPL = "build-impl.xml";
+ public static final String LOGCOMP = "log_comp.xml";
+ public static final String MESSAGE12 = "message_12.xml";
+ public static final String MSGATTACH = "msgAttach.xml";
+ public static final String REZ = "reZ003vExc23082309.xml";
+
+ protected static final ConcurrentHashMap<String, byte[]> byteCache = new ConcurrentHashMap<>();
+
+ @Param({BUILDIMPL,LOGCOMP,MESSAGE12,MSGATTACH,REZ})
+ protected String doc;
+
+ /**
+ * Gets a given InputStream as a byte-array.
+ *
+ * @param is stream to read from
+ * @return byte-array
+ * @throws IOException if things go crazy-crazy
+ */
+ private static byte[] getBytes(InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+
+ int available = is.available();
+ while (available > 0) {
+ int read = Math.min(b.length, available);
+
+ int actuallyRead = is.read(b, 0, read);
+ baos.write(b, 0, actuallyRead);
+
+ available = is.available();
+ }
+
+ is.close();
+ byte array[] = baos.toByteArray();
+ baos.close();
+
+ return array;
+ }
+
+ /**
+ * Gets a given resource as a byte-array.
+ *
+ * @param name resource to fetch
+ * @return byte-array
+ * @throws IOException if things go crazy-crazy
+ * @throws URISyntaxException if resource given doesn't match syntax
+ */
+ protected byte[] getFileBytesFromResource(String name) throws IOException, URISyntaxException {
+ byte[] bytes = byteCache.get(name);
+ if (bytes == null) {
+ bytes = getBytes(this.getClass().getResourceAsStream("/"
+ + AbstractXMLMicro.class.getPackage().getName().replace(".", "/")
+ + "/" + name));
+ byteCache.put(name, bytes);
+ }
+ return bytes;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/DOM.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class DOM extends AbstractXMLMicro {
+
+ @Benchmark
+ public Document testBuild() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ byte[] bytes = getFileBytesFromResource(doc);
+ InputSource source = new InputSource();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ source.setByteStream(bais);
+ return buildDocument(dbf, source);
+ }
+
+ @Benchmark
+ public Document testModify() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ byte[] bytes = getFileBytesFromResource(doc);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ InputSource source = new InputSource(bais);
+ Document doc1 = buildDocument(dbf, source);
+
+ modifyElementRecursive(doc1.getDocumentElement());
+ return doc1;
+ }
+
+ @Benchmark
+ public Document testWalk() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ byte[] bytes = getFileBytesFromResource(doc);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ InputSource source = new InputSource(bais);
+ Document doc1 = buildDocument(dbf, source);
+
+ walkElementRecursive(doc1.getDocumentElement());
+ return doc1;
+ }
+
+ private Document buildDocument(DocumentBuilderFactory dbf, InputSource source)
+ throws ParserConfigurationException, SAXException, IOException {
+ dbf.setValidating(false);
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ return docBuilder.parse(source);
+ }
+
+ // TODO Fix so it isn't recursive?
+ private static void walkElementRecursive(Element element) {
+ // loop through children
+ if (element.hasChildNodes()) {
+ Node child = element.getFirstChild();
+ while (child != null) {
+
+ // handle child by type
+ int type = child.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ walkElementRecursive((Element) child);
+ }
+ child = child.getNextSibling();
+ }
+ }
+ }
+
+ // TODO Fix so it isn't recursive?
+ private void modifyElementRecursive(Element element) {
+
+ // check for children present
+ if (element.hasChildNodes()) {
+
+ // loop through child nodes
+ boolean content = false;
+
+ // Should not be null since we already have made a .hasChildNodes()
+ // check.
+ Node child = element.getFirstChild();
+
+ do {
+ // Handle child by node type.
+ if (child.getNodeType() == Node.TEXT_NODE) {
+ String trimmed = child.getNodeValue().trim();
+ if (trimmed.length() == 0) {
+ // delete child if nothing but whitespace
+ element.removeChild(child);
+ } else {
+ // make sure we have the parent element information
+ content = true;
+ Document doc = element.getOwnerDocument();
+ String uri = element.getNamespaceURI();
+ String prefix = element.getPrefix();
+ content = true;
+
+ // Create a "text" element matching parent namespace.
+ Element text = (uri == null) ? doc.createElement("text") : doc.createElementNS(uri, prefix
+ + ":text");
+
+ // wrap the trimmed content with new element
+ text.appendChild(doc.createTextNode(trimmed));
+ element.replaceChild(text, child);
+
+ }
+ } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+ modifyElementRecursive((Element) child);
+ }
+
+ } while ((child = child.getNextSibling()) != null);
+
+ // check if we've seen any non-whitespace content for element
+ if (content) {
+ String prefix = element.getPrefix();
+ String uri = element.getNamespaceURI();
+ // add attribute flagging content found
+ if (prefix == null || prefix.length() == 0) {
+ element.setAttribute("text", "true");
+ } else {
+ element.setAttributeNS(uri, prefix + ":text", "true");
+ }
+
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/SAXUsingJDK.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Micro testing SAXParser performance using the JDK classes
+ */
+public class SAXUsingJDK extends AbstractXMLMicro {
+
+ @Benchmark
+ public XMLReader testParse() throws Exception {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ byte[] bytes = getFileBytesFromResource(doc);
+ spf.setValidating(false);
+ SAXParser parser = spf.newSAXParser();
+ XMLReader reader = parser.getXMLReader();
+ InputSource source = new InputSource();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ source.setByteStream(bais);
+ reader.parse(source);
+ return reader;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/STAX.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.TearDown;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class STAX extends AbstractXMLMicro {
+
+ /** Live data */
+ public Map<String, LinkedList<String>> liveData;
+
+ @Setup(Level.Iteration)
+ public void setupLiveData() {
+ Map<String, LinkedList<String>> map = new HashMap<>();
+ // Somewhere around 100 MB live, but fragmented to start with.
+ for (int i = 0; i < 1000; i++) {
+ LinkedList<String> list = new LinkedList<>();
+ String key = "Dummy linked list " + i;
+ list.add(key);
+ for (int j = 0; j < 1000; j++) {
+ list.add("Dummy string " + i + "." + j);
+ }
+ map.put(key, list);
+ }
+ // thread safe, will only be one
+ liveData = map;
+ }
+
+ @TearDown(Level.Iteration)
+ public void teardownLiveData() {
+ liveData = null;
+ }
+
+ @Benchmark
+ public int testParse() throws Exception {
+ int intDummy = 0;
+ byte[] bytes = getFileBytesFromResource(doc);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+
+ XMLStreamReader parser = factory.createXMLStreamReader(bais);
+ int acc;
+ do {
+ acc = parser.next();
+ intDummy += acc;
+ } while (acc != XMLStreamConstants.END_DOCUMENT);
+ return intDummy;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring the gain of removing array bound checks in various cases
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayBoundCheckRemoval {
+
+ private int[] a;
+ private int j, u, v;
+
+ @Setup
+ public void setup() {
+ a = new int[200];
+ }
+
+ @Benchmark
+ public int[] testForLoopAccess() throws Exception {
+ int[] a = this.a;
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ return a;
+ }
+
+ @Benchmark
+ public int[] testBubblesortStripped() throws Exception {
+ int[] a = this.a;
+ int limit = a.length;
+ int st = -1;
+
+ while (st < limit) {
+ st++;
+ limit--;
+ for (j = st; j < limit; j++) {
+ u = a[j];
+ v = a[j + 1];
+ }
+ }
+ return a;
+ }
+
+ @Benchmark
+ public int[] testBubblesort() throws Exception {
+ int[] a = this.a;
+ int j1;
+ int limit = a.length;
+ int st = -1;
+ while (st < limit) {
+ boolean flipped = false;
+ st++;
+ limit--;
+ for (j1 = st; j1 < limit; j1++) {
+ if (a[j1] > a[j1 + 1]) {
+ int T = a[j1];
+ a[j1] = a[j1 + 1];
+ a[j1 + 1] = T;
+ flipped = true;
+ }
+ }
+ if (!flipped) {
+ return a;
+ }
+ flipped = false;
+ for (j1 = limit; --j1 >= st; ) {
+ if (a[j1] > a[j1 + 1]) {
+ int T = a[j1];
+ a[j1] = a[j1 + 1];
+ a[j1 + 1] = T;
+ flipped = true;
+ }
+ }
+ if (!flipped) {
+ return a;
+ }
+ }
+ return a;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayClear {
+
+ @Param("100000")
+ private int arraySize;
+
+ private int[] sourceIntArray;
+
+ @Setup
+ public void setupSubclass() {
+ sourceIntArray = new int[arraySize];
+ for (int i = 0; i < arraySize; i += 1) {
+ sourceIntArray[i] = i;
+ }
+ }
+
+ @Benchmark
+ public int[] testArrayClear() throws Exception {
+ int[] intArray = new int[arraySize];
+ System.arraycopy(sourceIntArray, 0, intArray, 0, arraySize);
+ return intArray;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Stack;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmarking measuring ArrayStoreCheck-performance plus the ability of the optimizer to remove storechecks
+ * altogether.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@SuppressWarnings("rawtypes")
+@State(Scope.Thread)
+public class ArrayStoreCheck {
+
+ /** How large should the test-arrays be. */
+ public static final int TESTSIZE = 1000;
+
+ private Vector[] fromVectorArr, toVectorArr;
+
+ private Object[] fromObjectArr, toObjectArr;
+
+ private Object[] fromObject2Arr, toObject2Arr;
+
+ private Object[] fromObject3Arr, toObject3Arr;
+
+ private Object[] fromObject4Arr, toObject4Arr;
+
+ @Setup(Level.Iteration)
+ public void createArrays() {
+ fromVectorArr = new Vector[TESTSIZE];
+ toVectorArr = new Vector[TESTSIZE];
+
+ fromObjectArr = fromVectorArr;
+ toObjectArr = toVectorArr;
+
+ /* set every almost 90% of all indices to an object. */
+ for (int i = 0; i < TESTSIZE; i++) {
+ fromVectorArr[i] = new Vector();
+ }
+ for (int i = 0; i < TESTSIZE; i += 10) {
+ fromVectorArr[i] = null;
+ }
+
+ fromObject2Arr = new Vector[TESTSIZE][1][][][];
+ toObject2Arr = new Vector[TESTSIZE][1][][][];
+
+ fromObject3Arr = new Stack[TESTSIZE][1][][][];
+ toObject3Arr = new Vector[TESTSIZE][1][][][];
+
+ fromObject4Arr = new Object[TESTSIZE];
+ toObject4Arr = new Comparable[TESTSIZE];
+ /* set every two indices to an object. */
+ for (int i = 0; i < TESTSIZE; i += 2) {
+ fromObject4Arr[i] = new String("apa?");
+ }
+ }
+
+ /**
+ * Test that loads from an Vector[] and stores in another Vector[]. The local types of the arrays are both Vector[].
+ * Hopefully we only will do a runtime check that we are storing in an exact Vector[].
+ */
+ @Benchmark
+ public void testArrayStoreCheckRT1() throws Exception {
+ Vector[] localFromArray = fromVectorArr;
+ Vector[] localToArray = toVectorArr;
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localFromArray[i];
+ }
+ }
+
+ /**
+ * Test that stores a newly created Vector in a Vector[]. The local type of the array is Vector[]. Hopefully we only
+ * will do a runtime check that we are storing in the same Vector[].
+ */
+ @Benchmark
+ public void testArrayStoreCheckRT2() throws Exception {
+ Vector[] localToArray = toVectorArr;
+ Vector localVector = new Vector();
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localVector;
+ }
+ }
+
+ /**
+ * Test that loads from a Vector[] and stores in the same Vector[]. Hopefully we only will remove the storecheck
+ * altogether due to the fact that the arrays are the same (and easily proven that they are they same).
+ */
+ @Benchmark
+ public void testArrayStoreCheckRemove1() throws Exception {
+ Vector[] localToArray = toVectorArr;
+ for (int i = 2; i < TESTSIZE; i++) {
+ localToArray[i] = localToArray[i - 2];
+ }
+ }
+
+ /**
+ * Test that loads from a Vector[] and stores in another Vector[]. The local types of the arrays are both Object[].
+ * This should be a tricky case where we statically have no clue what type the arrays actually are of. We should have
+ * to do a complex check.
+ */
+ @Benchmark
+ public void testArrayStoreCheckComplex1() throws Exception {
+ Object[] localFromArray = fromObjectArr;
+ Object[] localToArray = toObjectArr;
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localFromArray[i];
+ }
+ }
+
+ /**
+ * Test that loads from a Vector[][][][] and stores in another Vector[][][][]. The local types of the arrays are both
+ * Object[]. This should be a tricky case where we statically have no clue what type the arrays actually are of. We
+ * should have to do a complex check. Difference from complex1-test is that the actual types of the arrays are
+ * multi-dimensioned.
+ */
+ @Benchmark
+ public void testArrayStoreCheckComplex2() throws Exception {
+ Object[] localFromArray = fromObject2Arr;
+ Object[] localToArray = toObject2Arr;
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localFromArray[i];
+ }
+ }
+
+ /**
+ * Test that loads from a Stack[][][][] and stores in a Vector[][][][]. The local types of the arrays are both
+ * Object[]. This should be a tricky case where we statically have no clue what type the arrays actually are of. We
+ * should have to do a complex check. Difference from complex2-test is that the actual types of the from-array is
+ * different from the actual type of the to-array.
+ */
+ @Benchmark
+ public void testArrayStoreCheckComplex3() throws Exception {
+ Object[] localFromArray = fromObject3Arr;
+ Object[] localToArray = toObject3Arr;
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localFromArray[i];
+ }
+ }
+
+ /**
+ * Test that loads from a Object[] and stores in a Comparable[]. The local types of the arrays are both Object[]. This
+ * should be a tricky case where we statically have no clue what type the arrays actually are of. We should have to do
+ * a complex check. The interesting part with this test is that the destination array is an interface array.
+ */
+ @Benchmark
+ public void testArrayStoreCheckComplex4() throws Exception {
+ Object[] localFromArray = fromObject4Arr;
+ Object[] localToArray = toObject4Arr;
+
+ for (int i = 0; i < TESTSIZE; i++) {
+ localToArray[i] = localFromArray[i];
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring effect of loop optimizations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CopyLoop {
+
+ private MyString s;
+ private Buf b;
+
+ @Setup
+ public void setup() {
+ s = new MyString("foobarba");
+ b = new Buf();
+ }
+
+ /**
+ * Basic implementation, as a Java programmer would write it.
+ */
+ @Benchmark
+ public void testCharAtLoop() throws Exception {
+ for (int i = 0; i < s.length(); i++) {
+ int c = s.charAt(i);
+ b.byteBuf[i] = (byte) c;
+ }
+ }
+
+ /** Inline charAt and remove the redundant bounds checks. */
+ @Benchmark
+ public void testInlineCharAtLoop() throws Exception {
+ for (int i = 0; i < s.count; i++) {
+ int c = s.value[i + s.offset];
+ b.byteBuf[i] = (byte) c;
+ }
+ }
+
+ /**
+ * Unroll the loop (I cheat here because I know that the String will always be an even length, real implementation
+ * would require a pre-loop).
+ */
+ @Benchmark
+ public void testInlineAndUnrollCharAtLoop() throws Exception {
+ int startI = 0;
+ if ((s.count & 0xFFFE) != s.count) {
+ int c = s.value[s.offset];
+ b.byteBuf[0] = (byte) c;
+ startI = 1;
+ }
+ for (int i = startI; i < s.count - 1; i += 2) {
+ int c = s.value[i + s.offset];
+ int d = s.value[i + s.offset + 1];
+ b.byteBuf[i] = (byte) c;
+ b.byteBuf[i + 1] = (byte) d;
+ }
+ }
+
+ /** Hoist computation of constants outside of the loop. */
+ @Benchmark
+ public void testInlineAndUnrollAndHoistCharAtLoop() throws Exception {
+ byte[] byteBuf = b.byteBuf;
+ if (byteBuf == null) {
+ throw new NullPointerException();
+ }
+ char[] value = s.value;
+ int offset = s.offset;
+
+ int startI = offset;
+
+ if ((s.count & 0xFFFE) != s.count) {
+ int c = value[offset];
+ byteBuf[0] = (byte) c;
+ startI++;
+ }
+
+ int maxI = s.count + offset - 1;
+ for (int i = startI; i < maxI; i += 2) {
+ int c = value[i];
+ int d = value[i + 1];
+ byteBuf[i] = (byte) c;
+ byteBuf[i + 1] = (byte) d;
+ }
+ }
+
+ private static class Buf {
+ private byte[] byteBuf = new byte[100];
+ }
+
+ public static final class MyString {
+ private char value[];
+
+ private int offset;
+
+ private int count;
+
+ public MyString(String original) {
+ value = original.toCharArray();
+ offset = 0;
+ count = value.length;
+ }
+
+ public int length() {
+ return count;
+ }
+
+ public char charAt(int index) {
+ if ((index < 0) || (index >= count)) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return value[index + offset];
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/DivRem.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests speed of division and remainder calculations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class DivRem {
+
+ private static final int ARRAYSIZE = 500;
+
+ /* instance fields for the constant int division tests. */
+ public int[] intValues, intValues2;
+
+ /* instance fields for the constant long division tests. */
+ public long[] longValues, longValues2;
+
+ /* instance fields for the tests using the testdr-method. */
+ public long[] drLongValues1, drLongValues2;
+
+ public long[] drLongValuesAsInts1, drLongValuesAsInts2;
+
+ @Setup
+ public void setupSubclass() {
+ Random r = new Random(4711);
+
+ intValues = new int[ARRAYSIZE];
+ intValues2 = new int[ARRAYSIZE];
+ longValues = new long[ARRAYSIZE];
+ longValues2 = new long[ARRAYSIZE];
+
+ for (int i = 0; i < ARRAYSIZE; i++) {
+ intValues[i] = r.nextInt();
+ if (intValues[i] == 0) {
+ intValues[i] = 5353;
+ }
+ intValues2[i] = r.nextInt();
+
+ longValues[i] = r.nextLong();
+ if (longValues[i] == 0) {
+ longValues[i] = 5353L;
+ }
+ longValues2[i] = r.nextLong();
+ }
+
+ /* generate random longs for 32-64 tests */
+
+ drLongValues1 = new long[ARRAYSIZE];
+ drLongValues2 = new long[ARRAYSIZE];
+ drLongValuesAsInts1 = new long[ARRAYSIZE];
+ drLongValuesAsInts2 = new long[ARRAYSIZE];
+ for (int i = 0; i < ARRAYSIZE; i++) {
+ long l = r.nextLong();
+ if (l == 0L) {
+ l++;
+ }
+ drLongValues1[i] = l;
+ drLongValuesAsInts1[i] = (long) (int) l;
+ l = r.nextLong();
+ if (l == 0L) {
+ l++;
+ }
+ drLongValues2[i] = l;
+ drLongValuesAsInts2[i] = (long) (int) l;
+ }
+ }
+
+ /**
+ * Tests integer division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to
+ * a multiplication instead.
+ */
+ @Benchmark
+ public int testIntDivConstantDivisor() {
+ int dummy = 0;
+ for (int i = 0; i < intValues.length; i++) {
+ dummy += intValues[i] / 49;
+ }
+ return dummy;
+ }
+
+ /**
+ * Tests long division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to a
+ * multiplication instead.
+ */
+ @Benchmark
+ public long testLongDivConstantDivisor() {
+ long dummy = 0;
+ for (int i = 0; i < longValues.length; i++) {
+ dummy += longValues[i] / 49L + longValues[i] / 0x4949494949L;
+ }
+ return dummy;
+ }
+
+ /**
+ * Tests integer remainder with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to
+ * two multiplications instead.
+ */
+ @Benchmark
+ public int testIntRemConstantDivisor() {
+ int dummy = 0;
+ for (int i = 0; i < intValues.length; i++) {
+ dummy += intValues[i] % 49;
+ }
+ return dummy;
+ }
+
+ /**
+ * Tests long division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to a
+ * multiplication instead.
+ */
+ @Benchmark
+ public long testLongRemConstantDivisor() {
+ long dummy = 0;
+ for (int i = 0; i < longValues.length; i++) {
+ dummy += longValues[i] % 49L + longValues[i] % 0x4949494949L;
+ }
+ return dummy;
+ }
+
+ /**
+ * Tests integer division with a variable divisor. This benchmark is mainly here to be a comparison against the
+ * benchmark that performs both divisions and remainder calculations.
+ */
+ @Benchmark
+ public int testIntDivVariableDivisor() {
+ int dummy = 0;
+ for (int i = 0; i < intValues.length; i++) {
+ dummy += intValues2[i] / intValues[i];
+ }
+ return dummy;
+ }
+
+ /**
+ * Tests integer division and remainder with a variable divisor. Both calculations are performed with the same
+ * divisor, so a JVM should not have to perform two complex calculations. Either a division followed by a
+ * multiplication, or on X86 using idiv, where the reminder is also returned from the idiv instruction.
+ */
+ @Benchmark
+ public int testIntDivRemVariableDivisor() {
+ int dummy = 0;
+ for (int i = 0; i < intValues.length; i++) {
+ dummy += intValues2[i] / intValues[i];
+ dummy += intValues2[i] % intValues[i];
+ }
+ return dummy;
+ }
+
+ @Benchmark
+ public long test64DivRem64() {
+ long dummy = 0;
+ for (int i = 0; i < drLongValues1.length; i++) {
+ long l1 = drLongValues1[i];
+ long l2 = drLongValues2[i];
+ dummy += l1 / l2;
+ dummy += l1 % l2;
+ }
+ return dummy;
+ }
+
+ @Benchmark
+ public long test32DivRem32() {
+ long dummy = 0;
+ for (int i = 0; i < drLongValuesAsInts1.length; i++) {
+ long l1 = drLongValuesAsInts1[i];
+ long l2 = drLongValuesAsInts2[i];
+ dummy += l1 / l2;
+ dummy += l1 % l2;
+ }
+ return dummy;
+ }
+
+ @Benchmark
+ public long test64DivRem32() {
+ long dummy = 0;
+ for (int i = 0; i < drLongValues1.length; i++) {
+ long l1 = drLongValues1[i];
+ long l2 = drLongValuesAsInts2[i];
+ dummy += l1 / l2;
+ dummy += l1 % l2;
+ }
+ return dummy;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Explosion.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests that the JVM performs object explosion (or some sort of stack allocation).
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Explosion {
+
+ @Param("5")
+ private int len;
+
+ @Benchmark
+ public void testHashtableExplosion(Blackhole bh) throws Exception {
+ Object o = new Object();
+ Object[] oa = new Object[len];
+ for (int i = 0; i < len; i++) {
+ oa[i] = new Object();
+ }
+
+ Hashtable<Object, Object> h = new Hashtable<>();
+
+ for (int i = 0; i < len; i++) {
+ h.put(oa[i], o);
+ }
+
+ Enumeration<Object> e = h.elements();
+ while (e.hasMoreElements()) {
+ bh.consume(e.nextElement());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InnerClassNullRef {
+
+ class Pickles {
+ int count;
+
+ public Pickles(int x) {
+ count = x;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int x) {
+ count = x;
+ }
+ }
+
+ class BurgerStand {
+ public void makeBurgers() {
+ if (pickles != null) {
+ // add a pickle
+ pickles.setCount(pickles.getCount() - 1);
+ }
+ }
+ }
+
+ class BurgerStandNull {
+ public void makeBurgers() {
+ if (picklesNull != null) {
+ // add a pickle
+ picklesNull.setCount(picklesNull.getCount() - 1);
+ }
+ }
+ }
+
+ private BurgerStand bs;
+ private BurgerStandNull bsNull;
+ private Pickles pickles;
+ private Pickles picklesNull;
+
+ @Setup
+ public void setup() {
+ bs = new BurgerStand();
+ bsNull = new BurgerStandNull();
+ pickles = new Pickles(42);
+ }
+
+ @Benchmark
+ public void refIsNull() {
+ bsNull.makeBurgers();
+ }
+
+ @Benchmark
+ public void refIsNotNull() {
+ bs.makeBurgers();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InterfaceCalls {
+
+ interface AnInterface {
+ public int getInt();
+ }
+
+ interface SecondInterface {
+ public int get1();
+ }
+
+ interface OnlyHasOneImplInterface {
+ public int getLong();
+ }
+
+ interface AloneInterface {
+ public int getNumber();
+ }
+
+ class SingleImplementor implements OnlyHasOneImplInterface {
+ public int getLong() {
+ return 1;
+ }
+ }
+
+ class Extender1 extends SingleImplementor {
+ }
+
+ class FirstClass implements AnInterface {
+ public int getInt() {
+ return 1;
+ }
+ }
+
+ class SecondClass implements AnInterface {
+ public int getInt() {
+ return 2;
+ }
+ }
+
+ class ThirdClass implements AnInterface {
+ public int getInt() {
+ return -3;
+ }
+ }
+
+ class FourthClass implements AnInterface {
+ public int getInt() {
+ return -4;
+ }
+ }
+
+ class FifthClass implements AnInterface {
+ public int getInt() {
+ return -5;
+ }
+ }
+
+ class MultiClass1 implements AnInterface, SecondInterface {
+ public int get1() {
+ return 1;
+ }
+
+ public int getInt() {
+ return 2;
+ }
+ }
+
+ class MultiClass2 implements AnInterface, SecondInterface {
+ public int get1() {
+ return -1;
+ }
+
+ public int getInt() {
+ return -2;
+ }
+ }
+
+ class Aloner implements AloneInterface {
+ public int getNumber() {
+ return 7;
+ }
+ }
+
+ public Object dummy1;
+
+ public Object dummy2;
+
+ public Object dummy3;
+
+ public AnInterface multi1a, multi2a;
+
+ public SecondInterface multi1b, multi2b;
+
+ public Object multic, multic2;
+
+ public AnInterface[] as = new AnInterface[5];
+
+ public AnInterface multi;
+
+ public OnlyHasOneImplInterface single1;
+
+ public OnlyHasOneImplInterface single2;
+
+ public AloneInterface alone;
+
+ int count;
+
+ @Setup
+ public void setupSubclass() {
+ dummy1 = new FirstClass();
+ dummy2 = new SecondClass();
+ dummy3 = new ThirdClass();
+ as[0] = new FirstClass();
+ as[1] = new SecondClass();
+ as[2] = new ThirdClass();
+ as[3] = new FourthClass();
+ as[4] = new FifthClass();
+ MultiClass1 mc1 = new MultiClass1();
+ multi1a = mc1;
+ multi1b = mc1;
+ multic = mc1;
+ MultiClass2 mc2 = new MultiClass2();
+ multi2a = mc2;
+ multi2b = mc2;
+ multic2 = mc2;
+ single1 = new SingleImplementor();
+ single2 = new Extender1();
+ alone = new Aloner();
+ }
+
+ private void swapMultiParts() {
+ AnInterface tmpa = multi1a;
+ SecondInterface tmpb = multi1b;
+ multi1a = multi2a;
+ multi2a = tmpa;
+ multi1b = multi2b;
+ multi2b = tmpb;
+ }
+
+ @SuppressWarnings("unused")
+ private void swapMulti() {
+ Object tmp = multic;
+ multic = multic2;
+ multic2 = tmp;
+ }
+
+ /**
+ * Tests a call where there are multiple implementors but only one of the implementors is every used here so the
+ * call-site is monomorphic
+ */
+ @Benchmark
+ public int testMonomorphic() {
+ return as[0].getInt();
+ }
+
+ /** Tests a interface call that only has one single implementation */
+ @Benchmark
+ public int testSingle() {
+ return alone.getNumber();
+ }
+
+ /**
+ * Tests a call where there is a single implementation but multiple classes that inherit that implementation and both
+ * these implementors are used.
+ */
+ @Benchmark
+ public int testSingle2() {
+ OnlyHasOneImplInterface oi;
+ if ((count & 1) == 0) {
+ oi = single1;
+ } else {
+ oi = single2;
+ }
+ count++;
+ return oi.getLong();
+ }
+
+ /**
+ * Tests calling two different interface methods in two different interfaces on the same receiver. Make sure to switch
+ * between two different types of receivers to achieve polymorhpism
+ */
+ @Benchmark
+ public void testCall2Poly2(Blackhole bh) {
+ bh.consume(multi1a.getInt());
+ bh.consume(multi1b.get1());
+ swapMultiParts();
+ }
+
+ @Benchmark
+ public int testCallMulti1Poly2NoSwap() {
+ return multi1a.getInt();
+ }
+
+ /**
+ * This test goes together with Multi2 below It tests if a class implements multiple interfaces if the different
+ * interfaces take different amounts of time (They do for hotspot)
+ */
+ @Benchmark
+ public int testCallMulti1Poly2() {
+ swapMultiParts();
+ return multi1a.getInt();
+ }
+
+ /**
+ * This test goes together with Multi2 below It tests if a class implements multiple interfaces if the different
+ * interfaces take different amounts of time (They do for hotspot)
+ */
+ @Benchmark
+ public int testCallMulti2Poly2() {
+ swapMultiParts();
+ return multi1b.get1();
+ }
+
+ /** Interface call with three different receivers */
+ @Benchmark
+ public void testCallPoly3(Blackhole bh) {
+ for (int kk = 0; kk < 3; kk++) {
+ bh.consume(as[kk].getInt());
+ }
+ }
+
+ /** Interface call with five different receivers. */
+ @Benchmark
+ public void testCallPoly5(Blackhole bh) {
+ for (int kk = 0; kk < 3; kk++) {
+ bh.consume(as[kk].getInt());
+ }
+ }
+
+ int l;
+
+ /**
+ * Interface call address computation within loop but the receiver preexists the loop and the ac can be moved outside
+ * of the loop
+ */
+ @Benchmark
+ public int testAC1() {
+ AnInterface ai = as[l];
+ l = 1 - l;
+ return ai.getInt();
+ }
+
+ /** Tests an interface cast followed by an interface call. */
+ @Benchmark
+ public int testInterfaceCastAndCall() throws Exception {
+ return ((AnInterface) dummy1).getInt() + ((AnInterface) dummy2).getInt()
+ + ((AnInterface) dummy3).getInt();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Tests speed of multiplication calculations with constants.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Multiplication {
+
+ @Param("500")
+ private int arraySize;
+
+ private long[] longArraySmall, longArrayBig;
+
+ @Setup
+ public void setupSubclass() {
+ longArraySmall = new long[arraySize];
+ longArrayBig = new long[arraySize];
+
+ /*
+ * small values always have higher 32 bits cleared. big values always
+ * have higher 32 bits set.
+ */
+ for (int i = 0; i < arraySize; i++) {
+ longArraySmall[i] = 100L * i + i;
+ longArrayBig[i] = ((100L * i + i) << 32) + 4543 + i * 4;
+ }
+ }
+
+ /* helper for small constant benchmarks. */
+ private static long smallConstantHelper(long[] values) {
+ long sum = 0;
+ for (long value : values) {
+ sum += value * 453543L;
+ }
+ return sum;
+ }
+
+ /* helper for big constant benchmarks. */
+ private static long bigConstantHelper(long[] values) {
+ long sum = 0;
+ for (long value : values) {
+ sum += value * 4554345533543L;
+ }
+ return sum;
+ }
+
+ /**
+ * Test multiplications of longs. One of the operands is a small constant and the other is a variable that always is
+ * small.
+ */
+ @Benchmark
+ public long testLongSmallVariableSmallConstantMul() {
+ return smallConstantHelper(longArraySmall);
+ }
+
+ /**
+ * Test multiplications of longs. One of the operands is a big constant and the other is a variable that always is
+ * small.
+ */
+ @Benchmark
+ public long testLongSmallVariableBigConstantMul() {
+ return bigConstantHelper(longArraySmall);
+ }
+
+ /**
+ * Test multiplications of longs. One of the operands is a small constant and the other is a variable that always is
+ * big.
+ */
+ @Benchmark
+ public long testLongBigVariableSmallConstantMul() {
+ return smallConstantHelper(longArrayBig);
+ }
+
+ /**
+ * Test multiplications of longs. One of the operands is a big constant and the other is a variable that always is
+ * big.
+ */
+ @Benchmark
+ public long testLongBigVariableBigConstantMul() {
+ return bigConstantHelper(longArrayBig);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests how well the JVM can remove stores after allocation of objects.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class PostAllocationStores {
+
+ /** Tests allocation with explicit stores of null/zero to all fields. */
+ @Benchmark
+ public Object testAllocationWithNullStores() throws Exception {
+ return new TestWithNullStores();
+ }
+
+ /**
+ * Tests allocation with explicit stores of non-null/non-zero to all fields. This test exists as a complement to the
+ * one above.
+ */
+ @Benchmark
+ public Object testAllocationWithNonNullStores() throws Exception {
+ return new TestWithNonNullStores();
+ }
+
+ /** Tests allocation with explicit stores of null/zero to all fields, where all fields are volatile. */
+ @Benchmark
+ public Object testAllocationWithNullVolatileStores() throws Exception {
+ return new TestWithNullVolatileStores();
+ }
+
+ /** Tests allocation without any explicit stores to any fields. */
+ @Benchmark
+ public Object testAllocationWithoutStores() throws Exception {
+ return new TestWithoutStores();
+ }
+
+ static class TestWithNullStores {
+ Object objectField1;
+ Object objectField2;
+ Object objectField3;
+ int intField1;
+ int intField2;
+ long longField1;
+
+ public TestWithNullStores() {
+ objectField1 = null;
+ objectField2 = null;
+ objectField3 = null;
+ intField1 = 0;
+ intField2 = 0;
+ longField1 = 0L;
+ }
+ }
+
+ static class TestWithNonNullStores {
+ Object objectField1;
+ Object objectField2;
+ Object objectField3;
+ int intField1;
+ int intField2;
+ long longField1;
+
+ public TestWithNonNullStores() {
+ objectField1 = this;
+ objectField2 = this;
+ objectField3 = this;
+ intField1 = 4;
+ intField2 = 7;
+ longField1 = 2L;
+ }
+ }
+
+ static class TestWithNullVolatileStores {
+ volatile Object objectField1;
+ volatile Object objectField2;
+ volatile Object objectField3;
+ volatile int intField1;
+ volatile int intField2;
+ volatile long longField1;
+
+ public TestWithNullVolatileStores() {
+ objectField1 = null;
+ objectField2 = null;
+ objectField3 = null;
+ intField1 = 0;
+ intField2 = 0;
+ longField1 = 0L;
+ }
+ }
+
+ static class TestWithoutStores {
+ Object objectField1;
+ Object objectField2;
+ Object objectField3;
+ int intField1;
+ int intField2;
+ long longField1;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test spill code generation.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SpillCode {
+
+ @Param("10")
+ private int iterations;
+
+ private int dummy;
+
+ private int doSomeCalcsInLargeBlockWithInts(int start, int iter) {
+
+ int a1, a2, a3, a4;
+ int b1, b2, b3, b4;
+ int c1, c2, c3, c4;
+ int d1, d2, d3, d4;
+ int e1, e2, e3, e4;
+ int f1, f2, f3, f4;
+ int g1, g2, g3, g4;
+ int h1, h2, h3, h4;
+
+ // a1 = b1 = c1 = d1 = e1 = f1 = g1 = h1 = (start % 2);
+ a2 = b2 = c2 = d2 = e2 = f2 = g2 = h2 = (start % 2);
+ a3 = b3 = c3 = d3 = e3 = f3 = g3 = h3 = (start % 4);
+ a4 = b4 = c4 = d4 = e4 = f4 = g4 = h4 = (start % 8);
+
+ for (int i = 0; i < iter; i++) {
+
+ // for each section, only x1 needs to survive.
+
+ // a1 = a2 = a3 = a4 = (start + a1) % 2;
+ a1 = start;
+ a1 = a1 + a2 + a3 + a4;
+ a2 = a1 + a2 + a3 + a4;
+ a3 = a1 + a2 + a3 + a4;
+ a4 = a1 + a2 + a3 + a4;
+ a1 = a1 + a2 + a3 + a4;
+ a2 = a1 + a2 + a3 + a4;
+ a3 = a1 + a2 + a3 + a4;
+ a4 = a1 + a2 + a3 + a4;
+ a1 = a1 + a2 + a3 + a4;
+ a2 = a1 + a2 + a3 + a4;
+ a3 = a1 + a2 + a3 + a4;
+ a4 = a1 + a2 + a3 + a4;
+
+ // b1 = b2 = b3 = b4 = (a4 + b1) % 2;
+ b1 = a4;
+ b1 = b1 + b2 + b3 + b4;
+ b2 = b1 + b2 + b3 + b4;
+ b3 = b1 + b2 + b3 + b4;
+ b4 = b1 + b2 + b3 + b4;
+ b1 = b1 + b2 + b3 + b4;
+ b2 = b1 + b2 + b3 + b4;
+ b3 = b1 + b2 + b3 + b4;
+ b4 = b1 + b2 + b3 + b4;
+ b1 = b1 + b2 + b3 + b4;
+ b2 = b1 + b2 + b3 + b4;
+ b3 = b1 + b2 + b3 + b4;
+ b4 = b1 + b2 + b3 + b4;
+
+ // c1 = c2 = c3 = c4 = (b4 + c1) % 2;
+ c1 = b4;
+ c1 = c1 + c2 + c3 + c4;
+ c2 = c1 + c2 + c3 + c4;
+ c3 = c1 + c2 + c3 + c4;
+ c4 = c1 + c2 + c3 + c4;
+ c1 = c1 + c2 + c3 + c4;
+ c2 = c1 + c2 + c3 + c4;
+ c3 = c1 + c2 + c3 + c4;
+ c4 = c1 + c2 + c3 + c4;
+ c1 = c1 + c2 + c3 + c4;
+ c2 = c1 + c2 + c3 + c4;
+ c3 = c1 + c2 + c3 + c4;
+ c4 = c1 + c2 + c3 + c4;
+
+ // d1 = d2 = d3 = d4 = (c4 + d1) % 2;
+ d1 = c4;
+ d1 = d1 + d2 + d3 + d4;
+ d2 = d1 + d2 + d3 + d4;
+ d3 = d1 + d2 + d3 + d4;
+ d4 = d1 + d2 + d3 + d4;
+ d1 = d1 + d2 + d3 + d4;
+ d2 = d1 + d2 + d3 + d4;
+ d3 = d1 + d2 + d3 + d4;
+ d4 = d1 + d2 + d3 + d4;
+ d1 = d1 + d2 + d3 + d4;
+ d2 = d1 + d2 + d3 + d4;
+ d3 = d1 + d2 + d3 + d4;
+ d4 = d1 + d2 + d3 + d4;
+
+ // e1 = e2 = e3 = e4 = (d4 + e1) % 2;
+ e1 = d4;
+ e1 = e1 + e2 + e3 + e4;
+ e2 = e1 + e2 + e3 + e4;
+ e3 = e1 + e2 + e3 + e4;
+ e4 = e1 + e2 + e3 + e4;
+ e1 = e1 + e2 + e3 + e4;
+ e2 = e1 + e2 + e3 + e4;
+ e3 = e1 + e2 + e3 + e4;
+ e4 = e1 + e2 + e3 + e4;
+ e1 = e1 + e2 + e3 + e4;
+ e2 = e1 + e2 + e3 + e4;
+ e3 = e1 + e2 + e3 + e4;
+ e4 = e1 + e2 + e3 + e4;
+
+ // f1 = f2 = f3 = f4 = (e4 + f1) % 2;
+ f1 = e4;
+ f1 = f1 + f2 + f3 + f4;
+ f2 = f1 + f2 + f3 + f4;
+ f3 = f1 + f2 + f3 + f4;
+ f4 = f1 + f2 + f3 + f4;
+ f1 = f1 + f2 + f3 + f4;
+ f2 = f1 + f2 + f3 + f4;
+ f3 = f1 + f2 + f3 + f4;
+ f4 = f1 + f2 + f3 + f4;
+ f1 = f1 + f2 + f3 + f4;
+ f2 = f1 + f2 + f3 + f4;
+ f3 = f1 + f2 + f3 + f4;
+ f4 = f1 + f2 + f3 + f4;
+
+ // g1 = g2 = g3 = g4 = (f4 + g1) % 2;
+ g1 = f4;
+ g1 = g1 + g2 + g3 + g4;
+ g2 = g1 + g2 + g3 + g4;
+ g3 = g1 + g2 + g3 + g4;
+ g4 = g1 + g2 + g3 + g4;
+ g1 = g1 + g2 + g3 + g4;
+ g2 = g1 + g2 + g3 + g4;
+ g3 = g1 + g2 + g3 + g4;
+ g4 = g1 + g2 + g3 + g4;
+ g1 = g1 + g2 + g3 + g4;
+ g2 = g1 + g2 + g3 + g4;
+ g3 = g1 + g2 + g3 + g4;
+ g4 = g1 + g2 + g3 + g4;
+
+ // h1 = h2 = h3 = h4 = (g4 + h1) % 2;
+ h1 = g4;
+ h1 = h1 + h2 + h3 + h4;
+ h2 = h1 + h2 + h3 + h4;
+ h3 = h1 + h2 + h3 + h4;
+ h4 = h1 + h2 + h3 + h4;
+ h1 = h1 + h2 + h3 + h4;
+ h2 = h1 + h2 + h3 + h4;
+ h3 = h1 + h2 + h3 + h4;
+ h4 = h1 + h2 + h3 + h4;
+ h1 = h1 + h2 + h3 + h4;
+ h2 = h1 + h2 + h3 + h4;
+ h3 = h1 + h2 + h3 + h4;
+ h4 = h1 + h2 + h3 + h4;
+
+ start = h4;
+ }
+
+ return start;
+ }
+
+ /**
+ * The test runs a loop with many local variables. The issue it reproduces is that if handled wrong, too many variables
+ * are put on and referenced on stack. The number of iterations is taken from global variable, to prevent static loop
+ * unrolling. Many of the variables used in the larger loop are local inside the block and do dnot need to survive from
+ * one iteration to the next.
+ */
+ @Benchmark
+ public int testSpillForManyInts() throws Exception {
+ return doSomeCalcsInLargeBlockWithInts(dummy, iterations);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for removal of redundant stores. It's crucial for the tests to be valid that inlining and allocation is
+ * performed as described in this file.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StoreAfterStore {
+ public int s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8;
+
+ /**
+ * Test removal of redundant zero stores following an object allocation.
+ */
+ @Benchmark
+ public AllocAndZeroStoreHelper testAllocAndZeroStore() throws Exception {
+ return new AllocAndZeroStoreHelper(s1, s2, s3, s4, s5, s6, s7, s8);
+ }
+
+ /**
+ * Test removal of stores followed by stores to the same memory location.
+ */
+ @Benchmark
+ public StoreAndStoreHelper testStoreAndStore() throws Exception {
+ return new StoreAndStoreHelper(s1, s2, s3, s4, s5, s6, s7, s8);
+ }
+
+
+ /**
+ * Helper for alloc followed by zero store testing.
+ */
+ static class AllocAndZeroStoreHelper {
+ public volatile int vf1, vf2, vf3, vf4, vf5, vf6, vf7, vf8;
+
+ public static int s1, s2, s3, s4, s5, s6, s7, s8;
+
+ private AllocAndZeroStoreHelper() {
+ this.vf1 = 0;
+ this.vf2 = 0;
+ this.vf3 = 0;
+ this.vf4 = 0;
+ this.vf5 = 0;
+ this.vf6 = 0;
+ this.vf7 = 0;
+ this.vf8 = 0;
+ }
+
+ private AllocAndZeroStoreHelper(int l1, int l2, int l3, int l4, int l5, int l6, int l7, int l8) {
+ this(); // Redundant initialization to zero here
+
+ // dummy stores
+ s1 = l1;
+ s2 = l2;
+ s3 = l3;
+ s4 = l4;
+ s5 = l5;
+ s6 = l6;
+ s7 = l7;
+ s8 = l8;
+ }
+
+ }
+
+ /**
+ * Helper for store made redundant by subsequent store testing.
+ */
+ static class StoreAndStoreHelper {
+ public volatile int vf1, vf2, vf3, vf4, vf5, vf6, vf7, vf8;
+
+ private StoreAndStoreHelper() {
+ this.vf1 = -1;
+ this.vf2 = -1;
+ this.vf3 = -1;
+ this.vf4 = -1;
+ this.vf5 = -1;
+ this.vf6 = -1;
+ this.vf7 = -1;
+ this.vf8 = -1;
+ }
+
+ private StoreAndStoreHelper(int l1, int l2, int l3, int l4, int l5, int l6, int l7, int l8) {
+ this(); // Initialize all to -1 here, redundant wrt to the below stores
+
+ this.vf1 = l1;
+ this.vf2 = l2;
+ this.vf3 = l3;
+ this.vf4 = l4;
+ this.vf5 = l5;
+ this.vf6 = l6;
+ this.vf7 = l7;
+ this.vf8 = l8;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Straighten.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Various small benchmarks testing how well the optimizer straightens code.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Straighten {
+
+ private int[] intArr;
+ private long[] longArr;
+
+ @Setup
+ public void setupSubclass() {
+ int TEST_SIZE = 300;
+
+ Random r = new Random(453543);
+
+ /*
+ * initialize arrays with some values between 0 and 7.
+ */
+ intArr = new int[TEST_SIZE];
+ for (int i = 0; i < TEST_SIZE; i++) {
+ intArr[i] = r.nextInt(8);
+ }
+
+ longArr = new long[TEST_SIZE];
+ for (int i = 0; i < TEST_SIZE; i++) {
+ longArr[i] = (long) r.nextInt(8);
+ }
+
+ }
+
+ private int innerCandidate1int(int i) {
+ int j = 0;
+
+ if (i == 5) {
+ /* we know that i isn't 4 and is less than 7 here. */
+ j++;
+ }
+ if (i == 4) {
+ /* we know that i is less than 7 here. */
+ j += 2;
+ }
+ if (i < 7) {
+ /* we know that i is less than 7, so it isn't greater than 7. */
+ j += 4;
+ }
+ if (i > 7) {
+ j += 8;
+ }
+ return j;
+ }
+
+ /** Tests how well serial constant integer compares are straightened. */
+ @Benchmark
+ public int testStraighten1int() throws Exception {
+ int dummy = 0;
+ int[] arr = intArr;
+ for (int i : arr) {
+ dummy += innerCandidate1int(i);
+ }
+ return dummy;
+ }
+
+ private long innerCandidate1long(long l) {
+ long j = 0;
+
+ if (l == 5) {
+ /* we know that l isn't 4 and is less than 7 here. */
+ j++;
+ }
+ if (l == 4) {
+ /* we know that l is less than 7 here. */
+ j += 2;
+ }
+ if (l < 7) {
+ /* we know that l is less than 7, so it isn't greater than 7. */
+ j += 4;
+ }
+ if (l > 7) {
+ j += 8;
+ }
+ return j;
+ }
+
+ /** Tests how well serial constant long compares are straightened. */
+ @Benchmark
+ public int testStraighten1long() throws Exception {
+ int dummy = 0;
+ long[] arr = longArr;
+ for (long l : arr) {
+ dummy += innerCandidate1long(l);
+ }
+ return dummy;
+ }
+
+ private int innerCandidate2int(int i) {
+ int j;
+
+ if (i < 5) {
+ /* j becomes 3, so it should be straightened to j == 3 case below. */
+ j = 3;
+ } else {
+ /* j becomes 4, so it should be straightened to j == 4 case below. */
+ j = 4;
+ }
+
+ if (j == 4) {
+ i += 2;
+ }
+ if (j == 3) {
+ i += 4;
+ }
+ return i;
+ }
+
+ /** Tests how well constant integer definitions are straightened. */
+ @Benchmark
+ public int testStraighten2int() throws Exception {
+ int[] arr = intArr;
+ int dummy = 0;
+ for (int i : arr) {
+ dummy += innerCandidate2int(i);
+ }
+ return dummy;
+ }
+
+ private long innerCandidate2long(long l) {
+ long j;
+
+ if (l < 5) {
+ /* j becomes 3, so it should be straightened to j == 3 case below. */
+ j = 3;
+ } else {
+ /* j becomes 4, so it should be straightened to j == 4 case below. */
+ j = 4;
+ }
+
+ if (j == 4) {
+ l += 2;
+ }
+ if (j == 3) {
+ l += 4;
+ }
+ return l;
+ }
+
+ /** Tests how well constant long definitions are straightened. */
+ @Benchmark
+ public int testStraighten2long() throws Exception {
+ int dummy = 0;
+ long[] arr = longArr;
+ for (long l : arr) {
+ dummy += innerCandidate2long(l);
+ }
+ return dummy;
+ }
+
+ private int innerCandidate3int(int i, int j) {
+ int k = 0;
+
+ if (i == j) {
+ k++;
+ }
+ if (i != j) {
+ k += 2;
+ }
+ if (i < j) {
+ k += 4;
+ }
+ return k;
+ }
+
+ /**
+ * Tests how well variable integer compares are straightened.
+ */
+ @Benchmark
+ public int testStraighten3int() throws Exception {
+ int dummy = 0;
+ int[] arr = intArr;
+ for (int i = 0; i < arr.length - 1; i++) {
+ dummy += innerCandidate3int(arr[i], arr[i + 1]);
+ }
+ return dummy;
+ }
+
+ private long innerCandidate3long(long i, long j) {
+ long k = 0;
+
+ if (i == j) {
+ k++;
+ }
+ if (i != j) {
+ k += 2;
+ }
+ if (i < j) {
+ k += 4;
+ }
+ return k;
+ }
+
+ /** Tests how well variable long compares are straightened. */
+ @Benchmark
+ public int testStraighten3long() throws Exception {
+ int dummy = 0;
+ long[] arr = longArr;
+ for (int i = 0; i < arr.length - 1; i++) {
+ dummy += innerCandidate3long(arr[i], arr[i + 1]);
+ }
+ return dummy;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class WriteBarrier {
+
+ // For array references
+ public static final int NUM_REFERENCES_SMALL = 32;
+ public static final int NUM_REFERENCES_LARGE = 2048;
+
+ // For array update tests
+ private Object[] theArraySmall;
+ private Object[] realReferencesSmall;
+ private Object[] nullReferencesSmall;
+ private int[] indicesSmall;
+
+ private Object[] theArrayLarge;
+ private Object[] realReferencesLarge;
+ private Object[] nullReferencesLarge;
+ private int[] indicesLarge;
+
+ // For field update tests
+ public Referencer head = null;
+ public Referencer tail = null;
+
+ // For random number generation
+ private int m_w;
+ private int m_z;
+
+ // For field references
+ public class Referencer {
+ Referencer next = null;
+ Referencer() {
+ this.next = null;
+ }
+ void append(Referencer r) {
+ this.next = r;
+ }
+ void clear() {
+ this.next = null;
+ }
+ }
+
+ @Setup
+ public void setup() {
+ theArraySmall = new Object[NUM_REFERENCES_SMALL];
+ realReferencesSmall = new Object[NUM_REFERENCES_SMALL];
+ nullReferencesSmall = new Object[NUM_REFERENCES_SMALL];
+ indicesSmall = new int[NUM_REFERENCES_SMALL];
+
+ theArrayLarge = new Object[NUM_REFERENCES_LARGE];
+ realReferencesLarge = new Object[NUM_REFERENCES_LARGE];
+ nullReferencesLarge = new Object[NUM_REFERENCES_LARGE];
+ indicesLarge = new int[NUM_REFERENCES_LARGE];
+
+ m_w = (int) System.currentTimeMillis();
+ Random random = new Random();
+ m_z = random.nextInt(10000) + 1;
+
+ for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+ indicesSmall[i] = get_random() % (NUM_REFERENCES_SMALL - 1);
+ realReferencesSmall[i] = new Object();
+ }
+
+ for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+ indicesLarge[i] = get_random() % (NUM_REFERENCES_LARGE - 1);
+ realReferencesLarge[i] = new Object();
+ }
+
+ // Build a small linked structure
+ this.head = new Referencer();
+ this.tail = new Referencer();
+ this.head.append(this.tail);
+
+ // This will (hopefully) promote objects to old space
+ // Run with -XX:+DisableExplicitGC to keep
+ // objects in young space
+ System.gc();
+ }
+
+ private int get_random() {
+ m_z = 36969 * (m_z & 65535) + (m_z >> 16);
+ m_w = 18000 * (m_w & 65535) + (m_w >> 16);
+ return Math.abs((m_z << 16) + m_w); /* 32-bit result */
+ }
+
+ @Benchmark
+ public void testArrayWriteBarrierFastPathRealSmall() {
+ for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+ theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = realReferencesSmall[indicesSmall[i]];
+ }
+ }
+
+ @Benchmark
+ public void testArrayWriteBarrierFastPathNullSmall() {
+ for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+ theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = nullReferencesSmall[indicesSmall[i]];
+ }
+ }
+
+ @Benchmark
+ public void testArrayWriteBarrierFastPathRealLarge() {
+ for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+ theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = realReferencesLarge[indicesLarge[i]];
+ }
+ }
+
+ @Benchmark
+ public void testArrayWriteBarrierFastPathNullLarge() {
+ for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+ theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = nullReferencesLarge[indicesLarge[i]];
+ }
+ }
+
+ @Benchmark()
+ public void testFieldWriteBarrierFastPath() {
+ // Shuffle everything around
+ this.tail.append(this.head);
+ this.head.clear();
+ this.head.append(this.tail);
+ this.tail.clear();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/gc/Alloc.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.gc;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Alloc {
+
+ public static final int LENGTH = 400;
+ public static final int ARR_LEN = 100;
+ public int largeLen = 100;
+ public int smalllen = 6;
+
+ @Benchmark
+ public void testLargeConstArray(Blackhole bh) throws Exception {
+ int localArrlen = ARR_LEN;
+ for (int i = 0; i < LENGTH; i++) {
+ Object[] tmp = new Object[localArrlen];
+ bh.consume(tmp);
+ }
+ }
+
+ @Benchmark
+ public void testLargeVariableArray(Blackhole bh) throws Exception {
+ int localArrlen = largeLen;
+ for (int i = 0; i < LENGTH; i++) {
+ Object[] tmp = new Object[localArrlen];
+ bh.consume(tmp);
+ }
+ }
+
+ @Benchmark
+ public void testSmallConstArray(Blackhole bh) throws Exception {
+ int localArrlen = largeLen;
+ for (int i = 0; i < LENGTH; i++) {
+ Object[] tmp = new Object[localArrlen];
+ bh.consume(tmp);
+ }
+ }
+
+ @Benchmark
+ public void testSmallObject(Blackhole bh) throws Exception {
+ FortyBytes localDummy = null;
+ for (int i = 0; i < LENGTH; i++) {
+ FortyBytes tmp = new FortyBytes();
+ tmp.next = localDummy;
+ localDummy = tmp;
+ bh.consume(tmp);
+ }
+ }
+
+ @Benchmark
+ public void testSmallVariableArray(Blackhole bh) throws Exception {
+ int localArrlen = smalllen;
+ for (int i = 0; i < LENGTH; i++) {
+ Object[] tmp = new Object[localArrlen];
+ bh.consume(tmp);
+ }
+ }
+
+ final class FortyBytes {
+ Object next;
+ int y, z, k, f, g, e, t;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/Capture0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates anonymous classes creation (for comparison with lambda)
+ *
+ * Naming convention:
+ * - inner_N - lambda captures N local variables
+ * - inner_this_N - lambda captures 'this' and N local variables
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Capture0 {
+
+ /*
+ * volatile is used in order to avoid constant propagation
+ * That is why the bench is relevant only on TSO platforms (x86, SPARC).
+ * ARM & PPC - TBD when necessary.
+ */
+ public volatile int wh0 = 0;
+ public volatile int wh1 = 1;
+ public volatile int wh2 = 2;
+ public volatile int wh3 = 3;
+ public volatile int wh4 = 4;
+ public volatile int wh5 = 5;
+ public volatile int wh6 = 6;
+ public volatile int wh7 = 7;
+
+ public String fortyTwo = "42";
+
+ @Benchmark()
+ public FunctionalInterface0 inner0(){
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return "42";
+ }
+ };
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 inner_1(){
+ final int l0 = wh0;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return "42" + l0;
+ }
+ };
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 inner_2(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return "42" + l0 + " " + l1;
+ }
+ };
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 inner_4(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ final int l2 = wh2;
+ final int l3 = wh3;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return "42" + l0 + " " + l1 + " " + l2 + " " + l3;
+ }
+ };
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 inner_8(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ final int l2 = wh2;
+ final int l3 = wh3;
+ final int l4 = wh4;
+ final int l5 = wh5;
+ final int l6 = wh6;
+ final int l7 = wh7;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return "42" + l0 + " " + l1 + " " + l2 + " " + l3 +
+ " " + l4 + " " + l5 + " " + l6 + " " + l7;
+ }
+ };
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 inner_this_0(){
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return fortyTwo;
+ }
+ };
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 inner_this_1(){
+ final int l0 = wh0;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return fortyTwo + l0;
+ }
+ };
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 inner_this_2(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return fortyTwo + l0 + " " + l1;
+ }
+ };
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 inner_this_4(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ final int l2 = wh2;
+ final int l3 = wh3;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
+ }
+ };
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 inner_this_8(){
+ final int l0 = wh0;
+ final int l1 = wh1;
+ final int l2 = wh2;
+ final int l3 = wh3;
+ final int l4 = wh4;
+ final int l5 = wh5;
+ final int l6 = wh6;
+ final int l7 = wh7;
+ return new FunctionalInterface0() {
+ @Override
+ public Object foo() {
+ return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
+ " " + l4 + " " + l5 + " " + l6 + " " + l7;
+ }
+ };
+ }
+
+//--------------------lambda part
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_00(){
+ return () -> "42";
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_01(){
+ int l0 = wh0;
+ return () -> "42" + l0;
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_02(){
+ int l0 = wh0;
+ int l1 = wh1;
+ return () -> "42" + l0 + " " + l1;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_04(){
+ int l0 = wh0;
+ int l1 = wh1;
+ int l2 = wh2;
+ int l3 = wh3;
+ return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3;
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_08(){
+ int l0 = wh0;
+ int l1 = wh1;
+ int l2 = wh2;
+ int l3 = wh3;
+ int l4 = wh4;
+ int l5 = wh5;
+ int l6 = wh6;
+ int l7 = wh7;
+ return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3 + " " + l4 + " " + l5 + " " + l6 + " " + l7;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_this_0(){
+ return () -> fortyTwo;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_this_1(){
+ int l0 = wh0;
+ return () -> fortyTwo + l0;
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_this_2(){
+ int l0 = wh0;
+ int l1 = wh1;
+ return () -> fortyTwo + l0 + " " + l1;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_this_4(){
+ int l0 = wh0;
+ int l1 = wh1;
+ int l2 = wh2;
+ int l3 = wh3;
+ return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
+ }
+
+
+ @Benchmark()
+ public FunctionalInterface0 lambda_this_8(){
+ int l0 = wh0;
+ int l1 = wh1;
+ int l2 = wh2;
+ int l3 = wh3;
+ int l4 = wh4;
+ int l5 = wh5;
+ int l6 = wh6;
+ int l7 = wh7;
+ return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
+ " " + l4 + " " + l5 + " " + l6 + " " + l7;
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/Capture2.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * measure lambda capture
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Capture2 {
+
+ public static class StaticInner implements Comparator<Integer> {
+ @Override
+ public int compare(Integer x, Integer y) {
+ return (x < y) ? -1 : ((x > y) ? 1 : 0);
+ }
+ }
+
+ public class InstanceInner implements Comparator<Integer> {
+ @Override
+ public int compare(Integer x, Integer y) {
+ return (x < y) ? -1 : ((x > y) ? 1 : 0);
+ }
+ }
+
+
+ @Benchmark()
+ public Comparator<Integer> anonymous(){
+ return new Comparator<Integer>() {
+ @Override
+ public int compare(Integer x, Integer y) {
+ return (x < y) ? -1 : ((x > y) ? 1 : 0);
+ }
+ };
+ }
+
+ @Benchmark()
+ public Comparator<Integer> inner(){
+ return new InstanceInner();
+ }
+
+ @Benchmark()
+ public Comparator<Integer> inner_static(){
+ return new StaticInner();
+ }
+
+ @Benchmark()
+ public Comparator<Integer> lambda(){
+ return (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0);
+ }
+
+ public Comparator<Integer> mref_static(){
+ return Integer::compare;
+ }
+
+ @Benchmark()
+ public Comparator<Integer> mref_unbound(){
+ return Integer::compareTo;
+ }
+
+ @Benchmark()
+ public Comparator<Integer> mref_bound(){
+ return this::compareInteger;
+ }
+
+ public int compareInteger(Integer x, Integer y) {
+ return (x < y) ? -1 : ((x > y) ? 1 : 0);
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/CaptureMR.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates method reference capture
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class CaptureMR {
+
+ public static class Mock0 {
+ public Mock0() {
+ }
+ }
+
+ public static Object method_static() {
+ return "42";
+ }
+
+ public Object method_instance() {
+ return "42";
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 mref_static0(){
+ return CaptureMR::method_static;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 mref_bound0(){
+ return this::method_instance;
+ }
+
+ @Benchmark()
+ public FunctionalInterface0 mref_constructor0(){
+ return Mock0::new;
+ }
+
+
+//---------------------------
+
+ public static class Mock1 {
+ private Object oo;
+ public Mock1(Object o) {
+ oo = o;
+ }
+ }
+
+ public static Object method_static(Object bar) {
+ return "42" + bar;
+ }
+
+ public Object method_instance(Object bar) {
+ return "42" + bar;
+ }
+
+ @Benchmark()
+ public FunctionalInterface1 mref_static1(){
+ return CaptureMR::method_static;
+ }
+
+ @Benchmark()
+ public FunctionalInterface1 mref_bound1(){
+ return this::method_instance;
+ }
+
+ @Benchmark()
+ public FunctionalInterface1 mref_constructor1(){
+ return Mock1::new;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+/**
+ * Functional Interface for lambdas
+ * FunctionalInterfaceN - where N is number of parameters
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+public interface FunctionalInterface0 {
+
+ public Object foo();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface1.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+/**
+ * Functional Interface for lambdas
+ * FunctionalInterfaceN - where N is number of parameters
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+public interface FunctionalInterface1 {
+
+ public Object foo(Object bar);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap0 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1();
+ start2 = get2();
+ start4 = get4();
+ start8 = get8();
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0() {
+ return new TopLevel() {
+ @Override
+ public String getImage() {
+ return "GOT: ";
+ }
+ };
+ }
+
+ public static Level get1() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get0();
+ }
+ };
+ }
+
+ public static Level get2() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get1();
+ }
+ };
+ }
+
+ public static Level get3() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get2();
+ }
+ };
+ }
+
+ public static Level get4() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get3();
+ }
+ };
+ }
+
+ public static Level get5() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get4();
+ }
+ };
+ }
+
+ public static Level get6() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get5();
+ }
+ };
+ }
+
+ public static Level get7() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get6();
+ }
+ };
+ }
+
+ public static Level get8() {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get7();
+ }
+ };
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap1.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap1 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1("capture me");
+ start2 = get2("capture me");
+ start4 = get4("capture me");
+ start8 = get8("capture me");
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0(String v) {
+ return new TopLevel() {
+ @Override
+ public String getImage() {
+ return "GOT: "+v;
+ }
+ };
+ }
+
+ public static Level get1(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get0(v);
+ }
+ };
+ }
+
+ public static Level get2(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get1(v);
+ }
+ };
+ }
+
+ public static Level get3(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get2(v);
+ }
+ };
+ }
+
+ public static Level get4(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get3(v);
+ }
+ };
+ }
+
+ public static Level get5(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get4(v);
+ }
+ };
+ }
+
+ public static Level get6(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get5(v);
+ }
+ };
+ }
+
+ public static Level get7(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get6(v);
+ }
+ };
+ }
+
+ public static Level get8(String v) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get7(v);
+ }
+ };
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap4.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap4 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1("capture me", "and me", "me too", "wait! what about me?");
+ start2 = get2("capture me", "and me", "me too", "wait! what about me?");
+ start4 = get4("capture me", "and me", "me too", "wait! what about me?");
+ start8 = get8("capture me", "and me", "me too", "wait! what about me?");
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0(String v0, String v1, String v2, String v3) {
+ return new TopLevel() {
+ @Override
+ public String getImage() {
+ return "GOT: " + v0 + "," + v1 + "," + v2 + "," + v3;
+ }
+ };
+ }
+
+ public static Level get1(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get0(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get2(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get1(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get3(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get2(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get4(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get3(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get5(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get4(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get6(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get5(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get7(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get6(v0, v1, v2, v3);
+ }
+ };
+ }
+
+ public static Level get8(String v0, String v1, String v2, String v3) {
+ return new Level() {
+ @Override
+ public Level up() {
+ return get7(v0, v1, v2, v3);
+ }
+ };
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainBase.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+import org.openjdk.jmh.infra.Blackhole;
+
+public class ChainBase {
+
+ protected void process(Blackhole bh, Level start) {
+ Level curr = start;
+ while (true) {
+ curr = curr.up();
+ if(curr == null) break;
+ bh.consume(curr);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap0 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1();
+ start2 = get2();
+ start4 = get4();
+ start8 = get8();
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0() {
+ return () -> "GOT: ";
+ }
+
+ public static Level get1() {
+ return () -> get0();
+ }
+
+ public static Level get2() {
+ return () -> get1();
+ }
+
+ public static Level get3() {
+ return () -> get2();
+ }
+
+ public static Level get4() {
+ return () -> get3();
+ }
+
+ public static Level get5() {
+ return () -> get4();
+ }
+
+ public static Level get6() {
+ return () -> get5();
+ }
+
+ public static Level get7() {
+ return () -> get6();
+ }
+
+ public static Level get8() {
+ return () -> get7();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap1.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap1 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1("capture me");
+ start2 = get2("capture me");
+ start4 = get4("capture me");
+ start8 = get8("capture me");
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0(String v) {
+ return () -> "GOT: "+v;
+ }
+
+ public static Level get1(String v) {
+ return () -> get0(v);
+ }
+
+ public static Level get2(String v) {
+ return () -> get1(v);
+ }
+
+ public static Level get3(String v) {
+ return () -> get2(v);
+ }
+
+ public static Level get4(String v) {
+ return () -> get3(v);
+ }
+
+ public static Level get5(String v) {
+ return () -> get4(v);
+ }
+
+ public static Level get6(String v) {
+ return () -> get5(v);
+ }
+
+ public static Level get7(String v) {
+ return () -> get6(v);
+ }
+
+ public static Level get8(String v) {
+ return () -> get7(v);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap4.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap4 extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1("capture me", "and me", "me too", "wait! what about me?");
+ start2 = get2("capture me", "and me", "me too", "wait! what about me?");
+ start4 = get4("capture me", "and me", "me too", "wait! what about me?");
+ start8 = get8("capture me", "and me", "me too", "wait! what about me?");
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0(String v0, String v1, String v2, String v3) {
+ return () -> "GOT: " + v0 + "," + v1 + "," + v2 + "," + v3;
+ }
+
+ public static Level get1(String v0, String v1, String v2, String v3) {
+ return () -> get0(v0, v1, v2, v3);
+ }
+
+ public static Level get2(String v0, String v1, String v2, String v3) {
+ return () -> get1(v0, v1, v2, v3);
+ }
+
+ public static Level get3(String v0, String v1, String v2, String v3) {
+ return () -> get2(v0, v1, v2, v3);
+ }
+
+ public static Level get4(String v0, String v1, String v2, String v3) {
+ return () -> get3(v0, v1, v2, v3);
+ }
+
+ public static Level get5(String v0, String v1, String v2, String v3) {
+ return () -> get4(v0, v1, v2, v3);
+ }
+
+ public static Level get6(String v0, String v1, String v2, String v3) {
+ return () -> get5(v0, v1, v2, v3);
+ }
+
+ public static Level get7(String v0, String v1, String v2, String v3) {
+ return () -> get6(v0, v1, v2, v3);
+ }
+
+ public static Level get8(String v0, String v1, String v2, String v3) {
+ return () -> get7(v0, v1, v2, v3);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefBound.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainMrefBound extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1();
+ start2 = get2();
+ start4 = get4();
+ start8 = get8();
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public TopLevel get0() {
+ return () -> "GOT: ";
+ }
+
+ public Level get1() {
+ return this::get0;
+ }
+
+ public Level get2() {
+ return this::get1;
+ }
+
+ public Level get3() {
+ return this::get2;
+ }
+
+ public Level get4() {
+ return this::get3;
+ }
+
+ public Level get5() {
+ return this::get4;
+ }
+
+ public Level get6() {
+ return this::get5;
+ }
+
+ public Level get7() {
+ return this::get6;
+ }
+
+ public Level get8() {
+ return this::get7;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefUnbound.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainMrefUnbound extends ChainBase {
+
+ public Level start1;
+ public Level start2;
+ public Level start4;
+ public Level start8;
+
+ @Setup
+ public void init() {
+ start1 = get1();
+ start2 = get2();
+ start4 = get4();
+ start8 = get8();
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(1)
+ public void call1(Blackhole bh) {
+ process(bh, start1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(2)
+ public void call2(Blackhole bh) {
+ process(bh, start2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(4)
+ public void call4(Blackhole bh) {
+ process(bh, start4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(8)
+ public void call8(Blackhole bh) {
+ process(bh, start8);
+ }
+
+ public static TopLevel get0() {
+ return () -> "GOT: ";
+ }
+
+ public static Level get1() {
+ return ChainMrefUnbound::get0;
+ }
+
+ public static Level get2() {
+ return ChainMrefUnbound::get1;
+ }
+
+ public static Level get3() {
+ return ChainMrefUnbound::get2;
+ }
+
+ public static Level get4() {
+ return ChainMrefUnbound::get3;
+ }
+
+ public static Level get5() {
+ return ChainMrefUnbound::get4;
+ }
+
+ public static Level get6() {
+ return ChainMrefUnbound::get5;
+ }
+
+ public static Level get7() {
+ return ChainMrefUnbound::get6;
+ }
+
+ public static Level get8() {
+ return ChainMrefUnbound::get7;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/Level.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+/**
+ * Functional Interface.
+ */
+public interface Level {
+
+ public Level up();
+
+ default String getImage() {
+ return "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/TopLevel.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+/**
+ * Functional Interface as end of chain marker.
+ */
+public interface TopLevel extends Level {
+
+ @Override
+ default Level up() {
+ return null;
+ }
+
+ @Override
+ public String getImage();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannI.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntBinaryOperator;
+
+/**
+ * evaluates invocation costs in case of long recursive chains
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class AckermannI {
+
+ // ackermann(1,1748)+ ackermann(2,1897)+ ackermann(3,8); == 9999999 calls
+ public static final int Y1 = 1748;
+ public static final int Y2 = 1897;
+ public static final int Y3 = 8;
+
+ public static int ack(int x, int y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ ack(x - 1, 1) :
+ ack(x - 1, ack(x, y - 1)));
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public int func() {
+ return ack(1, Y1) + ack(2, Y2) + ack(3, Y3);
+ }
+
+ public static final IntBinaryOperator inner_ack =
+ new IntBinaryOperator() {
+ @Override
+ public int applyAsInt(int x, int y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ inner_ack.applyAsInt(x - 1, 1) :
+ inner_ack.applyAsInt(x - 1, inner_ack.applyAsInt(x, y - 1)));
+
+ }
+ };
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public int inner() {
+ return inner_ack.applyAsInt(1, Y1) + inner_ack.applyAsInt(2, Y2) + inner_ack.applyAsInt(3, Y3);
+ }
+
+ public static final IntBinaryOperator lambda_ack =
+ (x, y) -> x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ AckermannI.lambda_ack.applyAsInt(x - 1, 1) :
+ AckermannI.lambda_ack.applyAsInt(x - 1, AckermannI.lambda_ack.applyAsInt(x, y - 1)));
+
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public int lambda() {
+ return lambda_ack.applyAsInt(1, Y1) + lambda_ack.applyAsInt(2, Y2) + lambda_ack.applyAsInt(3, Y3);
+ }
+
+ public static final IntBinaryOperator mref_ack = AckermannI::mref_ack_helper;
+
+ public static int mref_ack_helper(int x, int y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ mref_ack.applyAsInt(x - 1, 1) :
+ mref_ack.applyAsInt(x - 1, mref_ack.applyAsInt(x, y - 1)));
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public int mref() {
+ return mref_ack.applyAsInt(1, Y1) + mref_ack.applyAsInt(2, Y2) + mref_ack.applyAsInt(3, Y3);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannL.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * evaluates invocation costs in case of long recursive chains
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class AckermannL {
+
+ // ackermann(1,1748)+ ackermann(2,1897)+ ackermann(3,8); == 9999999 calls
+ public static final int Y1 = 1748;
+ public static final int Y2 = 1897;
+ public static final int Y3 = 8;
+
+ public static Integer ack(Integer x, Integer y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ ack(x - 1, 1) :
+ ack(x - 1, ack(x, y - 1)));
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public Integer func() {
+ return ack(1, Y1) + ack(2, Y2) + ack(3, Y3);
+ }
+
+ public static final BinaryOperator<Integer> inner_ack =
+ new BinaryOperator<Integer>() {
+ @Override
+ public Integer apply(Integer x, Integer y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ inner_ack.apply(x - 1, 1) :
+ inner_ack.apply(x - 1, inner_ack.apply(x, y - 1)));
+ }
+ };
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public Integer inner() {
+ return inner_ack.apply(1, Y1) + inner_ack.apply(2, Y2) + inner_ack.apply(3, Y3);
+ }
+
+ public static final BinaryOperator<Integer> lambda_ack =
+ (x, y) -> x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ AckermannL.lambda_ack.apply(x - 1, 1) :
+ AckermannL.lambda_ack.apply(x - 1, AckermannL.lambda_ack.apply(x, y - 1)));
+
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public Integer lambda() {
+ return lambda_ack.apply(1, Y1) + lambda_ack.apply(2, Y2) + lambda_ack.apply(3, Y3);
+ }
+
+ public static final BinaryOperator<Integer> mref_ack = AckermannL::mref_ack_helper;
+
+ public static Integer mref_ack_helper(Integer x, Integer y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ mref_ack.apply(x - 1, 1) :
+ mref_ack.apply(x - 1, mref_ack.apply(x, y - 1)));
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public Integer mref() {
+ return mref_ack.apply(1, Y1) + mref_ack.apply(2, Y2) + mref_ack.apply(3, Y3);
+ }
+
+ public static final BinaryOperator<Integer> mref_ackIII = AckermannL::mref_ack_helperIII;
+
+ public static int mref_ack_helperIII(int x, int y) {
+ return x == 0 ?
+ y + 1 :
+ (y == 0 ?
+ mref_ackIII.apply(x - 1, 1) :
+ mref_ackIII.apply(x - 1, mref_ackIII.apply(x, y - 1)));
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(9999999)
+ public Integer mrefIII() {
+ return mref_ackIII.apply(1, Y1) + mref_ackIII.apply(2, Y2) + mref_ackIII.apply(3, Y3);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Function0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates invocation costs.
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Function0 {
+
+ public interface FunctionI {
+ int foo();
+ }
+
+ public interface FunctionL {
+ Integer foo();
+ }
+
+ private static int valueI = 40002; // bypass Integer.cache
+ private static Integer valueL = Integer.valueOf(valueI);
+
+ public int fooInstanceI() {
+ return valueI;
+ }
+
+ public static int fooStaticI() {
+ return valueI;
+ }
+
+ public Integer fooInstanceL() {
+ return valueL;
+ }
+
+ public static Integer fooStaticL() {
+ return valueL;
+ }
+
+ @Benchmark
+ public int baselineI() {
+ return fooInstanceI();
+ }
+
+ @Benchmark
+ public Integer baselineL() {
+ return fooInstanceL();
+ }
+
+ public final FunctionI anonymI =
+ new FunctionI() {
+ @Override
+ public int foo() {
+ return valueI;
+ }
+ };
+
+ public final FunctionL anonymL =
+ new FunctionL() {
+ @Override
+ public Integer foo() {
+ return valueL;
+ }
+ };
+
+ @Benchmark
+ public int innerI() {
+ return anonymI.foo();
+ }
+
+ @Benchmark
+ public Integer innerL() {
+ return anonymL.foo();
+ }
+
+ public final FunctionI lambdaI = () -> valueI;
+
+ public final FunctionL lambdaL = () -> valueL;
+
+ @Benchmark
+ public int lambdaI() {
+ return lambdaI.foo();
+ }
+
+ @Benchmark
+ public Integer lambdaL() {
+ return lambdaL.foo();
+ }
+
+ public final FunctionI mref_I2I = Function0::fooStaticI;
+ public final FunctionI mref_I2I_bound = this::fooInstanceI;
+
+ public final FunctionL mref_I2L = Function0::fooStaticI;
+ public final FunctionL mref_I2L_bound = this::fooInstanceI;
+
+ public final FunctionI mref_L2I = Function0::fooStaticL;
+ public final FunctionI mref_L2I_bound = this::fooInstanceL;
+
+ public final FunctionL mref_L2L = Function0::fooStaticL;
+ public final FunctionL mref_L2L_bound = this::fooInstanceL;
+
+ // mref naming
+ // sig1_sig2 where:
+ // sig1 - signature of the method referenced by method ref
+ // sig2 - FuntionalInterface signature
+
+ @Benchmark
+ public int mrefI_I() {
+ return mref_I2I.foo();
+ }
+
+ @Benchmark
+ public int mref_bndI_I() {
+ return mref_I2I_bound.foo();
+ }
+
+ @Benchmark
+ public Integer mrefI_L() {
+ return mref_I2L.foo();
+ }
+
+ @Benchmark
+ public Integer mref_bndI_L() {
+ return mref_I2L_bound.foo();
+ }
+
+ @Benchmark
+ public int mrefL_I() {
+ return mref_L2I.foo();
+ }
+
+ @Benchmark
+ public int mref_bndL_I() {
+ return mref_L2I_bound.foo();
+ }
+
+ @Benchmark
+ public Integer mrefL_L() {
+ return mref_L2L.foo();
+ }
+
+ @Benchmark
+ public Integer mref_bndL_L() {
+ return mref_L2L_bound.foo();
+ }
+
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Function1.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates invocation costs.
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Function1 {
+
+ public interface FunctionII {
+ int foo(int x);
+ }
+
+ public interface FunctionIL {
+ int foo(Integer x);
+ }
+
+ public interface FunctionLL {
+ Integer foo(Integer x);
+ }
+
+ private static final int LIMIT = 1024;
+
+ private final int[] dataI = new int[LIMIT + 1];
+ private final Integer[] dataL = new Integer[LIMIT + 1];
+
+ @Setup(Level.Iteration)
+ public void setup() {
+ for (int i = 0; i < dataI.length; i++) {
+ int value = ThreadLocalRandom.current().nextInt(10001,420000); // bypass Integer.cache
+ dataI[i] = value;
+ dataL[i] = value;
+ }
+ }
+
+
+
+ public int fooInstanceII(int x) {
+ return x;
+ }
+
+ public static int fooStaticII(int x) {
+ return x;
+ }
+
+ public int fooInstanceIL(Integer v) {
+ return v;
+ }
+
+ public static int fooStaticIL(Integer v) {
+ return v;
+ }
+
+ public Integer fooInstanceLL(Integer v) {
+ return v;
+ }
+
+ public static Integer fooStaticLL(Integer v) {
+ return v;
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void baselineII(Blackhole bh) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(fooInstanceII(dataI[i]));
+ }
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void baselineIL(Blackhole bh) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(fooInstanceIL(dataL[i]));
+ }
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void baselineLL(Blackhole bh) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(fooInstanceLL(dataL[i]));
+ }
+ }
+
+ public final FunctionII anonymII =
+ new FunctionII() {
+ @Override
+ public int foo(int x) {
+ return x;
+ }
+ };
+
+ public final FunctionIL anonymIL =
+ new FunctionIL() {
+ @Override
+ public int foo(Integer v) {
+ return v;
+ }
+ };
+
+ public final FunctionLL anonymLL =
+ new FunctionLL() {
+ @Override
+ public Integer foo(Integer v) {
+ return v;
+ }
+ };
+
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void innerII(Blackhole bh) {
+ processII(bh, anonymII);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void innerIL(Blackhole bh) {
+ processIL(bh, anonymIL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void innerLL(Blackhole bh) {
+ processLL(bh, anonymLL);
+ }
+
+ public final FunctionII lambdaII = x -> x;
+
+ public final FunctionIL lambdaIL = v -> v;
+
+ public final FunctionLL lambdaLL = v -> v;
+
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void lambdaII(Blackhole bh) {
+ processII(bh, lambdaII);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void lambdaIL(Blackhole bh) {
+ processIL(bh, lambdaIL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void lambdaLL(Blackhole bh) {
+ processLL(bh, lambdaLL);
+ }
+
+
+
+ public final FunctionII mref_II2II = Function1::fooStaticII;
+ public final FunctionII mref_II2II_bound = this::fooInstanceII;
+ public final FunctionIL mref_II2IL = Function1::fooStaticII;
+ public final FunctionIL mref_II2IL_bound = this::fooInstanceII;
+ public final FunctionLL mref_II2LL = Function1::fooStaticII;
+ public final FunctionLL mref_II2LL_bound = this::fooInstanceII;
+
+ public final FunctionII mref_IL2II = Function1::fooStaticIL;
+ public final FunctionII mref_IL2II_bound = this::fooInstanceIL;
+ public final FunctionIL mref_IL2IL = Function1::fooStaticIL;
+ public final FunctionIL mref_IL2IL_bound = this::fooInstanceIL;
+ public final FunctionLL mref_IL2LL = Function1::fooStaticIL;
+ public final FunctionLL mref_IL2LL_bound = this::fooInstanceIL;
+
+ public final FunctionII mref_LL2II = Function1::fooStaticLL;
+ public final FunctionII mref_LL2II_bound = this::fooInstanceLL;
+ public final FunctionIL mref_LL2IL = Function1::fooStaticLL;
+ public final FunctionIL mref_LL2IL_bound = this::fooInstanceLL;
+ public final FunctionLL mref_LL2LL = Function1::fooStaticLL;
+ public final FunctionLL mref_LL2LL_bound = this::fooInstanceLL;
+
+
+ // mref naming
+ // sig1_sig2 where:
+ // sig1 - signature of the method referenced by method ref
+ // sig2 - FuntionalInterface signature
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefII_II(Blackhole bh) {
+ processII(bh, mref_II2II);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndII_II(Blackhole bh) {
+ processII(bh, mref_II2II_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefII_IL(Blackhole bh) {
+ processIL(bh, mref_II2IL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndII_IL(Blackhole bh) {
+ processIL(bh, mref_II2IL_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefII_LL(Blackhole bh) {
+ processLL(bh, mref_II2LL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndII_LL(Blackhole bh) {
+ processLL(bh, mref_II2LL_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefIL_II(Blackhole bh) {
+ processII(bh, mref_IL2II);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndIL_II(Blackhole bh) {
+ processII(bh, mref_IL2II_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefIL_IL(Blackhole bh) {
+ processIL(bh, mref_IL2IL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndIL_IL(Blackhole bh) {
+ processIL(bh, mref_IL2IL_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefIL_LL(Blackhole bh) {
+ processLL(bh, mref_IL2LL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndIL_LL(Blackhole bh) {
+ processLL(bh, mref_IL2LL_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefLL_II(Blackhole bh) {
+ processII(bh, mref_LL2II);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndLL_II(Blackhole bh) {
+ processII(bh, mref_LL2II_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefLL_IL(Blackhole bh) {
+ processIL(bh, mref_LL2IL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndLL_IL(Blackhole bh) {
+ processIL(bh, mref_LL2IL_bound);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mrefLL_LL(Blackhole bh) {
+ processLL(bh, mref_LL2LL);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(LIMIT)
+ public void mref_bndLL_LL(Blackhole bh) {
+ processLL(bh, mref_LL2LL_bound);
+ }
+
+
+ private void processII(Blackhole bh, FunctionII func) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(func.foo(dataI[i]));
+ }
+ }
+
+ private void processIL(Blackhole bh, FunctionIL func) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(func.foo(dataL[i]));
+ }
+ }
+
+ private void processLL(Blackhole bh, FunctionLL func) {
+ for (int i = 0; i < LIMIT; i++) {
+ bh.consume(func.foo(dataL[i]));
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph0.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * N different lambdas each capture 0 variable
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph0 {
+
+
+ private static final int LIMIT = 16536;
+ private static final int OPS = 4;
+ private static final int OPERATIONS = OPS*LIMIT;
+
+ // <source of functional interface>_N; where N - how many different targets
+ private IntUnaryOperator[] inner_1;
+ private IntUnaryOperator[] inner_2;
+ private IntUnaryOperator[] inner_4;
+
+ private IntUnaryOperator[] lambda_1;
+ private IntUnaryOperator[] lambda_2;
+ private IntUnaryOperator[] lambda_4;
+
+ private IntUnaryOperator[] unbounded_mref_1;
+ private IntUnaryOperator[] unbounded_mref_2;
+ private IntUnaryOperator[] unbounded_mref_4;
+
+ private IntUnaryOperator[] bounded_mref_1;
+ private IntUnaryOperator[] bounded_mref_2;
+ private IntUnaryOperator[] bounded_mref_4;
+
+ @Setup(Level.Trial)
+ public void setup() {
+ setup_inner();
+ setup_lambda();
+ setup_unbounded_mref();
+ setup_bounded_mref();
+ }
+
+ private void setup_inner() {
+ inner_4 = new IntUnaryOperator[] {
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + 1;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + 2;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + 3;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + 4;
+ }
+ },
+ };
+ inner_2 = new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+ inner_1 = new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+ }
+
+ private void setup_lambda() {
+ lambda_4 = new IntUnaryOperator[] {
+ x -> x + 1,
+ x -> x + 2,
+ x -> x + 3,
+ x -> x + 4,
+ };
+ lambda_2 = new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+ lambda_1 = new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+ }
+
+ public static int func1(int x) {
+ return x + 1;
+ }
+
+ public static int func2(int x) {
+ return x + 2;
+ }
+
+ public static int func3(int x) {
+ return x + 3;
+ }
+
+ public static int func4(int x) {
+ return x + 4;
+ }
+
+ private void setup_unbounded_mref() {
+ unbounded_mref_4 = new IntUnaryOperator[] {
+ Morph0::func1,
+ Morph0::func2,
+ Morph0::func3,
+ Morph0::func4,
+ };
+ unbounded_mref_2 = new IntUnaryOperator[] { unbounded_mref_4[0], unbounded_mref_4[1], unbounded_mref_4[0], unbounded_mref_4[1], };
+ unbounded_mref_1 = new IntUnaryOperator[] { unbounded_mref_4[0], unbounded_mref_4[0], unbounded_mref_4[0], unbounded_mref_4[0], };
+ }
+
+ public int ifunc1(int x) {
+ return x + 1;
+ }
+
+ public int ifunc2(int x) {
+ return x + 2;
+ }
+
+ public int ifunc3(int x) {
+ return x + 3;
+ }
+
+ public int ifunc4(int x) {
+ return x + 4;
+ }
+
+ private void setup_bounded_mref() {
+ bounded_mref_4 = new IntUnaryOperator[] {
+ this::ifunc1,
+ this::ifunc2,
+ this::ifunc3,
+ this::ifunc4,
+ };
+ bounded_mref_2 = new IntUnaryOperator[] { bounded_mref_4[0], bounded_mref_4[1], bounded_mref_4[0], bounded_mref_4[1], };
+ bounded_mref_1 = new IntUnaryOperator[] { bounded_mref_4[0], bounded_mref_4[0], bounded_mref_4[0], bounded_mref_4[0], };
+ }
+
+ public void process(Blackhole bh, IntUnaryOperator[] operations) {
+ for (int i = 0; i < LIMIT; i++) {
+ for (IntUnaryOperator op : operations) {
+ bh.consume(op.applyAsInt(i));
+ }
+ }
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner1(Blackhole bh) {
+ process(bh, inner_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner2(Blackhole bh) {
+ process(bh, inner_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner4(Blackhole bh) {
+ process(bh, inner_4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda1(Blackhole bh) {
+ process(bh, lambda_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda2(Blackhole bh) {
+ process(bh, lambda_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda4(Blackhole bh) {
+ process(bh, lambda_4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref1(Blackhole bh) {
+ process(bh, unbounded_mref_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref2(Blackhole bh) {
+ process(bh, unbounded_mref_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref4(Blackhole bh) {
+ process(bh, unbounded_mref_4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref_bnd1(Blackhole bh) {
+ process(bh, bounded_mref_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref_bnd2(Blackhole bh) {
+ process(bh, bounded_mref_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void mref_bnd4(Blackhole bh) {
+ process(bh, bounded_mref_4);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph1.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * N different lambdas each capture 1 variable
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph1 {
+
+
+ private static final int LIMIT = 16536;
+ private static final int OPS = 4;
+ private static final int OPERATIONS = OPS*LIMIT;
+
+ // <source of functional interface>_N; where N - how many different targets
+ private IntUnaryOperator[] inner_1;
+ private IntUnaryOperator[] inner_2;
+ private IntUnaryOperator[] inner_4;
+
+ private IntUnaryOperator[] lambda_1;
+ private IntUnaryOperator[] lambda_2;
+ private IntUnaryOperator[] lambda_4;
+
+ @Setup(Level.Trial)
+ public void setup() {
+ setup_inner(1,2,3,4);
+ setup_lambda(1,2,3,4);
+ }
+
+ private void setup_inner(int a, int b, int c, int d) {
+ inner_4 = new IntUnaryOperator[] {
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + a;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + b;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + c;
+ }
+ },
+ new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + d;
+ }
+ },
+ };
+ inner_2 = new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+ inner_1 = new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+ }
+
+ private void setup_lambda(int a, int b, int c, int d) {
+ lambda_4 = new IntUnaryOperator[] {
+ x -> x + a,
+ x -> x + b,
+ x -> x + c,
+ x -> x + d,
+ };
+ lambda_2 = new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+ lambda_1 = new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+ }
+
+ public void process(Blackhole bh, IntUnaryOperator[] operations) {
+ for (int i = 0; i < LIMIT; i++) {
+ for (IntUnaryOperator op : operations) {
+ bh.consume(op.applyAsInt(i));
+ }
+ }
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner1(Blackhole bh) {
+ process(bh, inner_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner2(Blackhole bh) {
+ process(bh, inner_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner4(Blackhole bh) {
+ process(bh, inner_4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda1(Blackhole bh) {
+ process(bh, lambda_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda2(Blackhole bh) {
+ process(bh, lambda_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda4(Blackhole bh) {
+ process(bh, lambda_4);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph2.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * the same lambda capture different variables
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph2 {
+
+
+ private static final int LIMIT = 16536;
+ private static final int OPS = 4;
+ private static final int OPERATIONS = OPS*LIMIT;
+
+ // <source of functional interface>_N; where N - how many different targets
+ private IntUnaryOperator[] inner_1;
+ private IntUnaryOperator[] inner_2;
+ private IntUnaryOperator[] inner_4;
+
+ private IntUnaryOperator[] lambda_1;
+ private IntUnaryOperator[] lambda_2;
+ private IntUnaryOperator[] lambda_4;
+
+ @Setup(Level.Trial)
+ public void setup() {
+ setup_inner(1,2,3,4);
+ setup_lambda(1,2,3,4);
+ }
+
+ private void setup_inner(int a, int b, int c, int d) {
+ inner_4 = new IntUnaryOperator[] {
+ makeInner(a),
+ makeInner(b),
+ makeInner(c),
+ makeInner(d),
+ };
+ inner_2 = new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+ inner_1 = new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+ }
+
+ private IntUnaryOperator makeInner(final int a) {
+ return new IntUnaryOperator() {
+ @Override
+ public int applyAsInt(int x) {
+ return x + a;
+ }
+ };
+ }
+
+ private void setup_lambda(int a, int b, int c, int d) {
+ lambda_4 = new IntUnaryOperator[] {
+ makeLambda(a),
+ makeLambda(b),
+ makeLambda(c),
+ makeLambda(d),
+ };
+ lambda_2 = new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+ lambda_1 = new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+ }
+
+ private IntUnaryOperator makeLambda(int a) {
+ return x -> x + a;
+ }
+
+ public void process(Blackhole bh, IntUnaryOperator[] operations) {
+ for (int i = 0; i < LIMIT; i++) {
+ for (IntUnaryOperator op : operations) {
+ bh.consume(op.applyAsInt(i));
+ }
+ }
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner1(Blackhole bh) {
+ process(bh, inner_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner2(Blackhole bh) {
+ process(bh, inner_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void inner4(Blackhole bh) {
+ process(bh, inner_4);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda1(Blackhole bh) {
+ process(bh, lambda_1);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda2(Blackhole bh) {
+ process(bh, lambda_2);
+ }
+
+ @Benchmark
+ @OperationsPerInvocation(OPERATIONS)
+ public void lambda4(Blackhole bh) {
+ process(bh, lambda_4);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/InstanceOf.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests various usages of instanceof.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InstanceOf {
+
+ private static final int NOOFOBJECTS = 100;
+ private static final int NULLRATIO = 3;
+
+ public Date[] dateArray;
+ public Object[] objectArray;
+
+ @Setup
+ public void setup() {
+ dateArray = new Date[NOOFOBJECTS * NULLRATIO];
+ for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i += NULLRATIO) {
+ dateArray[i] = new Date();
+ }
+ objectArray = dateArray;
+ }
+
+ /**
+ * Performs "instanceof Cloneable" on objects that definitely are of that interface. It is not clear however whether
+ * the objects are null or not, therefore a simple nullcheck is all that should be left of here.
+ */
+ @Benchmark
+ @OperationsPerInvocation((NOOFOBJECTS * NULLRATIO))
+ public int instanceOfInterfacePartialRemove() {
+ int dummy = 0;
+ Date[] localArray = dateArray;
+ for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i++) {
+ if (localArray[i] instanceof Cloneable) {
+ dummy++;
+ }
+ }
+ return dummy;
+ }
+
+ /**
+ * Performs three serial instanceof statements on the same object for three different interfaces. The objects are
+ * 50% null, and all non-null are instanceof the last interface.
+ */
+ @Benchmark
+ @OperationsPerInvocation((NOOFOBJECTS * NULLRATIO))
+ public int instanceOfInterfaceSerial() {
+ int dummy = 0;
+ Object[] localArray = objectArray;
+ for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i++) {
+ if (localArray[i] instanceof Runnable) {
+ dummy += 1000;
+ } else if (localArray[i] instanceof CharSequence) {
+ dummy += 2000;
+ } else if (localArray[i] instanceof Serializable) {
+ dummy++;
+ }
+ }
+ return dummy;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/LockUnlock.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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 java.util.concurrent.TimeUnit;
+
+
+/**
+ * Benchmark class for simple lock unlock tests. Nothing big should ever go into this class.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class LockUnlock {
+
+ @Param("100")
+ private int innerCount;
+
+ public Object lockObject1;
+ public Object lockObject2;
+ public int factorial;
+ public int dummyInt1;
+ public int dummyInt2;
+
+ @Setup
+ public void setup() {
+ lockObject1 = new Object();
+ lockObject2 = new Object();
+ dummyInt1 = 47;
+ dummyInt2 = 11; // anything
+ }
+
+ /** Perform a synchronized on a local object within a loop. */
+ @Benchmark
+ public void testSimpleLockUnlock() {
+ Object localObject = lockObject1;
+ for (int i = 0; i < innerCount; i++) {
+ synchronized (localObject) {
+ dummyInt1++;
+ dummyInt2++;
+ }
+ }
+ }
+
+ /** Perform a recursive synchronized on a local object within a loop. */
+ @Benchmark
+ public void testRecursiveLockUnlock() {
+ Object localObject = lockObject1;
+ for (int i = 0; i < innerCount; i++) {
+ synchronized (localObject) {
+ synchronized (localObject) {
+ dummyInt1++;
+ dummyInt2++;
+ }
+ }
+ }
+ }
+
+ /** Perform two synchronized after each other on the same local object. */
+ @Benchmark
+ public void testSerialLockUnlock() {
+ Object localObject = lockObject1;
+ for (int i = 0; i < innerCount; i++) {
+ synchronized (localObject) {
+ dummyInt1++;
+ }
+ synchronized (localObject) {
+ dummyInt2++;
+ }
+ }
+ }
+
+ /**
+ * Performs recursive synchronizations on the same local object.
+ * <p/>
+ * Result is 3628800
+ */
+ @Benchmark
+ public void testRecursiveSynchronization() {
+ factorial = fact(10);
+ }
+
+ private synchronized int fact(int n) {
+ if (n == 0) {
+ return 1;
+ } else {
+ return fact(n - 1) * n;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/Throw.java Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+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.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests throwing exceptions.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Throw {
+
+ public static boolean alwaysTrue = true;
+ private static Object nullObject = null;
+ public Object useObject = new Object();
+
+ @Benchmark
+ public void throwSyncException(Blackhole bh) {
+ try {
+ throwingMethod();
+ } catch (Exception ex) {
+ bh.consume(useObject);
+ }
+ }
+
+ @Benchmark
+ public void throwASyncException(Blackhole bh) {
+ try {
+ throwNullpointer();
+ } catch (Exception ex) {
+ bh.consume(useObject);
+ }
+ }
+
+ @Benchmark
+ public void throwSyncExceptionUseException(Blackhole bh) {
+ try {
+ throwingMethod();
+ } catch (Exception ex) {
+ bh.consume(ex);
+ }
+ }
+
+ @Benchmark
+ public void throwSyncExceptionUseMessage(Blackhole bh) {
+ try {
+ throwingMethod();
+ } catch (Exception ex) {
+ bh.consume(ex.getMessage());
+ }
+ }
+
+ @Benchmark
+ public void throwSyncExceptionUseStacktrace(Blackhole bh) {
+ try {
+ throwingMethod();
+ } catch (Exception ex) {
+ bh.consume(ex.getStackTrace());
+ }
+ }
+
+ @Benchmark
+ public void throwWith16Frames(Blackhole bh) {
+ try {
+ throwingMethod(16);
+ } catch (Exception ex) {
+ bh.consume(useObject);
+ }
+ }
+
+ @Benchmark
+ public void throwWith32Frames(Blackhole bh) {
+ try {
+ throwingMethod(32);
+ } catch (Exception ex) {
+ bh.consume(useObject);
+ }
+ }
+
+ @Benchmark
+ public void throwWith64Frames(Blackhole bh) {
+ try {
+ throwingMethod(64);
+ } catch (Exception ex) {
+ bh.consume(useObject);
+ }
+ }
+
+ public void throwingMethod() throws Exception {
+ if (alwaysTrue) {
+ throw new Exception();
+ }
+ }
+
+ public void throwingMethod(int i) throws Exception {
+ if (i == 0) {
+ throw new Exception();
+ }
+ throwingMethod(i - 1);
+ }
+
+ public void throwNullpointer() {
+ nullObject.hashCode();
+ }
+}