📜 ⬆️ ⬇️

Performance of lambda expressions in Java 8

In mid-2013 with the release of Java 8, the language began to support lambda expressions, 4 years have passed since then, a lot of updates have been released, and the release of Java 9 is coming (which we will probably be able to see this year, despite constant postponements), so at the junction of times, I would like to take stock and evaluate the performance of the new in java and the old, like the world of the tool, giving it a quantitative assessment.
socmetr.lambda.comparison
Performance evaluations have been repeatedly made, as in the other points, the advantages and disadvantages of lambda expressions were discussed:

to the first can be attributed:
- simplify and shorten the code
- the possibility of implementing a functional style
- the possibility of parallel computing
to the second :
- decrease in productivity
- debug difficulty

A good technique and tests were described and used 5 years ago by the user dmmm ( https://habrahabr.ru/post/146718/ ), in fact, they were taken as a basis.
')
If, in short, the tests themselves were delivered with the LambdaJ project. dmmm added tests for the Guava project and corrected them after discussion with the habr-community (2012).

I (that is, blutovi ) rewritten all the lambda tests (since the tests took place on alpha versions of java, and in the current state the code is simply not compiled), the state of memory was also analyzed using Java Mission Control and a jfr file was attached for each test with the results. (Java Mission Control - JVM diagnostic and monitoring tool - available since java 7 update 40, as a result of combining the ideas of two JVMs: HotSpot from Sun and JRockit from Oracle).

How was it tested?


The junit tests themselves consist of three phases: collection initialization, idle execution, execution with statistics collection (time is counted only at the last stage, and memory analysis is carried out throughout the whole cycle).

Measurement time is as follows: for each of ziterations over time Y, a sequential invocation of the test-algorithm occurs. Upon its expiration, the arithmetic average time of algorithm execution is determined.  barYz:

 barYz= frac1nz sumi=0nzYi

by dividing the total time of its execution Yfor the number of times nwhich he had time to be executed. Based ziterations, we find the total average execution time of the algorithm:

 barY= frac1z sumi=0z barYiz

By magnitude z(number of iterations) and Y(time during which the test algorithm is being called) can be affected by changing the values ​​of the constants in the class ch.lambdaj.demo.AbstractMeasurementTest:

public static final int WARMUP_ITERATIONS_COUNT = 10; public static final int ITERATIONS_COUNT = 10; public static final int ITERATION_DURATION_MSEC = 1000; 

The tests were run with activated parameters for Java Mission Control, which allowed generating diagnostic files in automatic mode.

results


in absolute values (the smaller the better )
foriterateguavajdk8 lambda
time nsheap, Mbtime nsheap, Mbtime nsheap, Mbtime nsheap, Mb
Extract cars original cost220.4313200.6324188.1302266.2333
Age of youngest who bought for> 50k6367260424527163672606157278
Find buys of youngest person60362706411.425962062606235288
Find most bought car2356167242317158821932971190
Find the most costly sale497158.166431.6297196.182
Group sales by buyers and sellers1214425012053254825920618447242
Index cars by brand263.3289275.02972828226307.5278
Print all brands473.2355455.3365540.3281514.2337
Select all sales of a Ferrari199.366265.153210.4111200.265
Sort sales by cost1075741075741069721566124
Sum costs where both are males67.06372.958215.988413.7114
in relative values (100% is the base, the lower the better )
foriterateguavajdk8 lambda
timeheaptimeheaptimeheaptimeheap
Extract cars original cost117%104%107%107%100%100%142%110%
Age of youngest who bought for> 50k150%100%100%104%150%100%145%107%
Find buys of youngest person100%104%106%100%103%100%103%111%
Find most bought car100%100%103%102%250%116%126%114%
Find the most costly sale100%108%119%100%881%450%400%124%
Group sales by buyers and sellers147%121%146%123%100%100%223%117%
Index cars by brand100%128%104%131%1074%100%117%123%
Print all brands104%126%100%130%119%100%113%120%
Select all sales of a Ferrari100%125%133%100%106%209%100%123%
Sort sales by cost101%103%101%103%100%100%147%172%
Sum costs where both are males100%109%109%100%322%152%617%197%

findings


If you summarize, it can be noted that the same things with lambda-expressions can be implemented in different ways: however, even the best options for performance will be inferior to simple solutions, and not the best can significantly affect performance.

Thus, the iterative approach provides an opportunity to focus on execution speed , and Guava allows you to focus on the amount of memory used , minimizing it. Using lambda expressions seems to give only aesthetic pleasure (to my great surprise).

Any suggestions how to change and improve tests are welcome.

Links


Source: https://habr.com/ru/post/331030/


All Articles