Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stochastic Search to lambda expression

Thanks for all your help and sharing.

My question is in regards of the Stochastic Search. This technique is used to do approximations of data through a defined amount of cicles over a, an in general, mathematical calculation. Please see following code, I tried to reduce it to its minimum. My expectation is to have this code setup as a lambda expression, the for loop, I would like to have the best performance of it. I have some intents but I'm not sure if I got the most of it.

package stochasticsearch;
import java.util.Random;
public class StochasticSearch {
    public static double f(double x) {
        return -(x - 1) * (x - 1) + 2;
    }
    public static void main(String[] args) {
        final Random random = new Random();
        double startPointX = 0;
        double max = f(startPointX);
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            double index = 2 * random.nextDouble();
            if (f(index) > max) {
                max = f(index);
            }
        }
        System.out.println("Elapsed time: " + (System.currentTimeMillis() - begin));
        System.out.println("Maximum value y=f(x) is " + max);
    }
}

Thanks, have a nice day.

like image 703
ouribeb930 Avatar asked Oct 16 '22 18:10

ouribeb930


1 Answers

Your code completes in a little under 23 seconds on my system, and I was able to modify it so that it takes under 2 seconds. Here's what I found:

  • You're using Random when you could be using ThreadLocalRandom instead; this switch results in a relatively-large speedup.
  • You're calculating f(index) twice inside your for-loop in certain cases when it should only be computed once per iteration.
  • Because you're iterating over a large range of values, you could utilize a parallel stream instead; this results in a relatively-large speedup as well.
  • You're adding 2 to every result in f, so it's better to add it a single time once max has been calculated.

    public static double f(double x) {
        double y = x - 1;
        return -y * y;
    }
    
    public static void main(String[] args) {
        final ThreadLocalRandom random = ThreadLocalRandom.current();
    
        long begin = System.currentTimeMillis();
    
        double max = IntStream.range(0, 1_000_000_000)
                              .parallel()
                              .mapToDouble(i -> f(random.nextDouble() * 2))
                              .max()
                              .orElse(f(0)) + 2;
    
        System.out.println("Elapsed time: " + (System.currentTimeMillis() - begin));
        System.out.println("Maximum value y=f(x) is " + max);
    }
    
like image 58
Jacob G. Avatar answered Oct 20 '22 15:10

Jacob G.