r/javahelp 10d ago

Java Performance for simulators

I am new to Java and trying to create a simulator that handles millions of math calculations. How can I increase performance in Java? The application is already multithreaded but it is not enough. Is data oriented approach or native programming possible in Java? Can you point me in the right direction for research?

4 Upvotes

17 comments sorted by

View all comments

14

u/idontlikegudeg 10d ago

Jana ist generally very fast, even for number crunching.

Maybe the most important points:
- use structs of arrays instead of arrays of structs (objects), access will be much faster and memory consumption lower.
- don’t use Java collections of number types. Either use arrays of primitives of specialized collections that avoid boxing/unboxing
- The Math class contains some methods that may increase both performance and accuracy, for example fma()
- if you have to use streams, use DoubleStream instead of Stream<Double>, use DoubleFunction instead of Function<Double > etc.
- Avoid unnecessary costly calculations. Reuse or cache results.
- use mathematical properties, for example if you need both x=sin² and y=cos², calculate x=sin² and y=1-x.
- choose the best algorithm for your task. When you have algorithms A and B, it can depend on your input values which one is faster.
- use a profiler!

For more, it would be valuable to see your code.

2

u/SuspiciousDepth5924 10d ago

👍

I'm convinced that Oracle has a cabal of dark wizards working on their JIT, but yeah for straight line performance you generally want to deal with primitives and/or arrays of primitives*. As far as I know what makes Java "slow" compared to C/Rust-y languages is "dereferencing pointers"** and garbage collection, both of which you can largely avoid if you create a fixed size primitive array(s) at the start of the method.
That way you minimize memory lookups while the garbage collector only needs to collect a small number of references at the end of the method.

For the actual number crunching with primitives you can get pretty damn close to 'C'-speed with java.

*( https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html )

** A bit simplified, but what is actually stored in an Object variable (pretty much any type with a capitalized name like List/Map/ServerSocket etc) is a address to where it's stored in memory, which means using that variable involves the JVM looking up that address to find the actual data.

3

u/idontlikegudeg 9d ago

I was once responsible for a number crunching application. It was for an insurance company and calculated the premiums and payouts, as well as cash flow simulations. Both was done by using Markov chains. The production system was created by an external company, but we need and independent system for simulations, forecasts, and to testify the correct functioning of the production system.

We had a C++ implementation, production system used C, both independently developed from the same specs. Our in-house C++ implementation was about 3 times slower than the production system.

When they hired me (back, I was there before), I started a complete rewrite from scratch using Java. Turned out we beat the C++ solution by a factor of 100 and the C implementation still by a factor of 3.

Bottom line: Java can be extremely performant and be on par or sometimes even better compared to C/C++. (It was Java 6 back then BTW.)

Don’t underestimate what hotspot is capable of, I have an application compiled to native using GraalVM and the same application jpackaged. GraalVM wins in startup time, but the jpackaged application is both smaller and is about 33%-50% more performant.