How to optimise and be faster than Java?

If I understand correctly, there isn’t much to SIMD here since each run depends on the previous run.

In julia, by convention functions mutating one of their arguments have a ! appended to make it clear to a user that they’re modifying one of their arguments - this does not have an impact on performance though, just makes the intent clearer.

As for the benchmark, BenchmarkTools allows interpolating of outer variables with $ (like @btime f($x)) - this reduces overhead of retrieving the object. @time in contrast includes compilation time, while @btime doesn’t. Also, you might want to use a setup for the benchmark, not to throw it off by increasing the size of the array evermore (like this: @btime calcprojouter(x, 125) setup=(x = copy($pa))). Be sure to check the documentation of BenchmarkTools for more information.

One idea you could still try without modifying too much is precalculating all the variables before constructing the new Proj and just giving those values to the constructor directly instead of creating a new Proj with all zeros and then mutating it.