Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Probe reflection implementation with Lmbda library #25597

Closed
wants to merge 5 commits into from

Conversation

JackPGreen
Copy link
Contributor

@JackPGreen JackPGreen commented Oct 3, 2023

When accessing the data provided by MethodProbes/FieldProbes, reflection is used.

If instead, the lmbda library is used, access performance can be improved by nearly 2x.

In #25279 steps were taken to move from core Java reflection to MethodHandles to improve performance, but the dynamic nature of our access means the performance improvements cannot be fully realised.

A similar scenario exists with FieldProbes - a suggestion was to use VarHandles there, but the performance of this was worse.

In both scenarios, ideally the reference should be static final to allow compiler folding to occur, but this isn't possible when the Probes are resolved at runtime.

The lmbda library offers increased performance by internally generating a class, at runtime, that has a static final reference to the MethodHandle required, using ASM. And then wraps that in a functional interface to allow easy access.

I've implemented this - for both MethodProbes & FieldProbes and benchmarked it to compare access performance between:

  • Current Probe implementation
  • New probe-lmbda implementation
  • Direct access (i.e. no reflection) to understand the ceiling / reflective overhead

I've compared this for:

  • Primitive & reference types
  • Methods & fields

To get an overall picture of the effect of this change:

Probe Type Access Type Direct field/method invocation ns/op master ns/op probe-lmbda ns/op
long Field 0.5 2.6 1.3
Long Field 2.6 1.4
long Method 0.5 3.7 1.4
Long Method 1.5 1.4

It's nearly twice as fast, and there is no change in litter / memory allocation - both were already effectively 0 memory allocation.
However, it's still not as fast as direct access.

Full benchmark results:

Of note - JEP416 (Java 18+) is likely to make the current FieldProbe reflection access style slower, whereas the Lmbda implementation is unaffected - related investigation.

Changes:

  • FieldProbes and MethodProbes now extend MethodHandleProbe
    • both do minimal work to convert the Method or Field into a MethodHandle which MethodHandleProbe use
    • reduced duplicated code
  • Lmbda dependency added
  • JitPack repository added to get the latest version of Lmbda with a blocking bug fixed

Pros:

  • Faster
  • Probably other places in the system this can be applied

Cons:

  • Additional dependency
  • Dependency version sourced through JitPack at a specific commit because blocking bug fix is not in a released version

Fixes #25528

Breaking changes (list specific methods/types/messages):

  • Only internal classes

@JackPGreen JackPGreen added this to the 5.4 Backlog milestone Oct 3, 2023
@JackPGreen JackPGreen self-assigned this Oct 3, 2023
@hz-devops-test
Copy link

The job Hazelcast-pr-builder of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/hazelcast/src/main/java/com/hazelcast/internal/metrics/impl/MethodHandleProbe.java:150:9: Cyclomatic Complexity is 13 (max allowed is 12). [CyclomaticComplexity]
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/hazelcast/src/test/java/com/hazelcast/internal/metrics/impl/FieldProbeTest.java:127: Line has trailing spaces. [RegexpSingleline]
--------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.0:checkstyle (default) on project hazelcast: An error has occurred in Checkstyle report generation. Failed during checkstyle execution: There are 2 errors reported by Checkstyle 9.3 with /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/checkstyle/checkstyle.xml ruleset. -> [Help 1]
--------------------------
[ERROR] 
--------------------------
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
--------------------------
[ERROR] 
--------------------------
[ERROR] For more information about the errors and possible solutions, please read the following articles:
--------------------------
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
--------------------------
[ERROR] 
--------------------------
[ERROR] After correcting the problems, you can resume the build with the command
--------------------------
[ERROR]   mvn  -rf :hazelcast
--------------------------

@hz-devops-test
Copy link

The job Hazelcast-pr-compiler of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-compiler/hazelcast/src/main/java/com/hazelcast/internal/metrics/impl/MethodHandleProbe.java:150:9: Cyclomatic Complexity is 13 (max allowed is 12). [CyclomaticComplexity]
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-compiler/hazelcast/src/test/java/com/hazelcast/internal/metrics/impl/FieldProbeTest.java:127: Line has trailing spaces. [RegexpSingleline]
--------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.0:checkstyle (default) on project hazelcast: An error has occurred in Checkstyle report generation. Failed during checkstyle execution: There are 2 errors reported by Checkstyle 9.3 with /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-compiler/checkstyle/checkstyle.xml ruleset. -> [Help 1]
--------------------------
[ERROR] 
--------------------------
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
--------------------------
[ERROR] 
--------------------------
[ERROR] For more information about the errors and possible solutions, please read the following articles:
--------------------------
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
--------------------------
[ERROR] 
--------------------------
[ERROR] After correcting the problems, you can resume the build with the command
--------------------------
[ERROR]   mvn  -rf :hazelcast
--------------------------

@hz-devops-test
Copy link

The job Hazelcast-pr-builder of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/hazelcast/src/main/java/com/hazelcast/internal/metrics/impl/MethodHandleProbe.java:150:9: Cyclomatic Complexity is 13 (max allowed is 12). [CyclomaticComplexity]
--------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.0:checkstyle (default) on project hazelcast: An error has occurred in Checkstyle report generation. Failed during checkstyle execution: There is 1 error reported by Checkstyle 9.3 with /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/checkstyle/checkstyle.xml ruleset. -> [Help 1]
--------------------------
[ERROR] 
--------------------------
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
--------------------------
[ERROR] 
--------------------------
[ERROR] For more information about the errors and possible solutions, please read the following articles:
--------------------------
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
--------------------------
[ERROR] 
--------------------------
[ERROR] After correcting the problems, you can resume the build with the command
--------------------------
[ERROR]   mvn  -rf :hazelcast
--------------------------

@hz-devops-test
Copy link

The job Hazelcast-pr-compiler of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-compiler/hazelcast/src/main/java/com/hazelcast/internal/metrics/impl/MethodHandleProbe.java:150:9: Cyclomatic Complexity is 13 (max allowed is 12). [CyclomaticComplexity]
--------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.0:checkstyle (default) on project hazelcast: An error has occurred in Checkstyle report generation. Failed during checkstyle execution: There is 1 error reported by Checkstyle 9.3 with /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-compiler/checkstyle/checkstyle.xml ruleset. -> [Help 1]
--------------------------
[ERROR] 
--------------------------
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
--------------------------
[ERROR] 
--------------------------
[ERROR] For more information about the errors and possible solutions, please read the following articles:
--------------------------
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
--------------------------
[ERROR] 
--------------------------
[ERROR] After correcting the problems, you can resume the build with the command
--------------------------
[ERROR]   mvn  -rf :hazelcast
--------------------------

@hz-devops-test
Copy link

The job Hazelcast-pr-builder of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.146 s <<< FAILURE! -- in com.hazelcast.osgi.CheckDependenciesIT
--------------------------
[ERROR] com.hazelcast.osgi.CheckDependenciesIT.testNoMandatoryDependencyDeclared -- Time elapsed: 0.128 s <<< FAILURE!
--------------------------
[ERROR] Failures: 
--------------------------
[ERROR]   CheckDependenciesIT.testNoMandatoryDependencyDeclared:86->checkImport:124 Import org.lanternpowered.lmbda is not declared as optional
--------------------------
[ERROR] Tests run: 17, Failures: 1, Errors: 0, Skipped: 1
--------------------------
[ERROR] There are test failures.
--------------------------
--------------------------
-------TEST FAILURE-------
--------------------------
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   CheckDependenciesIT.testNoMandatoryDependencyDeclared:86->checkImport:124 Import org.lanternpowered.lmbda is not declared as optional
[INFO] 
[ERROR] Tests run: 17, Failures: 1, Errors: 0, Skipped: 1
[INFO] 
[INFO] 
[INFO] --- failsafe:3.1.2:verify (default) @ hazelcast ---
[INFO] Failsafe report directory: /home/jenkins/jenkins_slave/workspace/Hazelcast-pr-builder/hazelcast/target/failsafe-reports

[ERROR] There are test failures.

@hz-devops-test
Copy link

The job Hazelcast-pr-builder of your PR failed. (Hazelcast internal details: build log, artifacts).
Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log file
---------ERRORS-----------
--------------------------
[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 3.446 s <<< FAILURE! -- in com.hazelcast.jet.core.metrics.JobMetrics_NonSharedClusterTest
--------------------------
[ERROR] com.hazelcast.jet.core.metrics.JobMetrics_NonSharedClusterTest.when_noMetricCollectionYet_then_emptyMetrics -- Time elapsed: 3.289 s <<< FAILURE!
--------------------------
[ERROR] Failures: 
--------------------------
[ERROR]   JobMetrics_NonSharedClusterTest.when_noMetricCollectionYet_then_emptyMetrics:89
--------------------------
[ERROR] Tests run: 57966, Failures: 1, Errors: 0, Skipped: 213
--------------------------
[ERROR] There are test failures.
--------------------------
--------------------------
-------TEST FAILURE-------
--------------------------
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   JobMetrics_NonSharedClusterTest.when_noMetricCollectionYet_then_emptyMetrics:89
[INFO] 
[ERROR] Tests run: 57966, Failures: 1, Errors: 0, Skipped: 213
[INFO] 

[ERROR] There are test failures.

@JackPGreen
Copy link
Contributor Author

run-lab-run

@JackPGreen JackPGreen marked this pull request as ready for review October 10, 2023 17:07
@vbekiaris
Copy link
Contributor

Cons:
Additional dependency
Dependency version sourced through JitPack at a specific commit because blocking bug fix is not in a released version

I think that's a deal-breaker: we can't depend on unreleased / unstable versions of 3rd party dependencies.

In general, especially taking into account the embedded usage of Hazelcast JAR, we have always been reluctant to add dependencies to the main hazelcast artifact. There used to be a "zero dependency" policy; nowadays a few libraries are shaded in the artifact (jackson, snakeyaml), but they are still few.

@JackPGreen JackPGreen closed this Nov 10, 2023
@AyberkSorgun AyberkSorgun removed this from the 5.4 Backlog milestone Mar 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FieldProbes should make use of VarHandles
4 participants