Сообщение Re: Покажите, пожалуйста, профит от функционального программ от 04.08.2024 10:48
Изменено 04.08.2024 11:27 vsb
Re: Покажите, пожалуйста, профит от функционального программ
package test;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static java.lang.System.currentTimeMillis;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.DoubleSupplier;
import java.util.stream.IntStream;
public class Test {
public static void main(String[] args) {
run("Monte Carlo imperative", Test::monteCarloImperative, 10);
run("Monte Carlo functional single-threaded", () -> monteCarloFunctional(false), 10);
run("Monte Carlo functional multi-threaded", () -> monteCarloFunctional(true), 10);
}
static void run(String name, DoubleSupplier supplier, int count) {
long bestTimeMillis = Long.MAX_VALUE;
for (int counter = 0; counter < count; counter++) {
long startTimeMillis = currentTimeMillis();
supplier.getAsDouble();
long endTimeMillis = currentTimeMillis();
bestTimeMillis = min(bestTimeMillis, endTimeMillis - startTimeMillis);
}
System.out.printf("%s: best time %d ms%n", name, bestTimeMillis);
}
static final int ITERATIONS = 1_000_000_000;
static double monteCarloImperative() {
int hits = 0;
var random = ThreadLocalRandom.current();
for (int iteration = 0; iteration < ITERATIONS; iteration++) {
double x = random.nextDouble();
double y = random.nextDouble();
if (x * x + y * y <= 1) {
hits++;
}
}
return (double) hits / ITERATIONS * 4;
}
static double monteCarloFunctional(boolean parallel) {
IntStream stream;
if (parallel) {
stream = IntStream.range(0, ITERATIONS).parallel();
} else {
stream = IntStream.range(0, ITERATIONS);
}
int hits = stream
.map(iteration -> {
var random = ThreadLocalRandom.current();
double x = random.nextDouble();
double y = random.nextDouble();
return x * x + y * y <= 1 ? 1 : 0;
})
.sum();
return (double) hits / ITERATIONS * 4;
}
}
Monte Carlo imperative: best time 3183 ms
Monte Carlo functional single-threaded: best time 3205 ms
Monte Carlo functional multi-threaded: best time 473 ms
Функциональный стиль не проигрывает императивному для однопоточного кода (но это у меня получилось не с первого раза) и выигрывает примерно в 7 раза при использовании 8-ядерного процессора.
Re: Покажите, пожалуйста, профит от функционального программ
package test;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static java.lang.System.currentTimeMillis;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.DoubleSupplier;
import java.util.stream.IntStream;
public class Test {
public static void main(String[] args) {
run("Monte Carlo imperative", Test::monteCarloImperative, 10);
run("Monte Carlo functional single-threaded", () -> monteCarloFunctional(false), 10);
run("Monte Carlo functional multi-threaded", () -> monteCarloFunctional(true), 10);
}
static void run(String name, DoubleSupplier supplier, int count) {
long bestTimeMillis = Long.MAX_VALUE;
for (int counter = 0; counter < count; counter++) {
long startTimeMillis = currentTimeMillis();
supplier.getAsDouble();
long endTimeMillis = currentTimeMillis();
bestTimeMillis = min(bestTimeMillis, endTimeMillis - startTimeMillis);
}
System.out.printf("%s: best time %d ms%n", name, bestTimeMillis);
}
static final int ITERATIONS = 1_000_000_000;
static double monteCarloImperative() {
int hits = 0;
var random = ThreadLocalRandom.current();
for (int iteration = 0; iteration < ITERATIONS; iteration++) {
double x = random.nextDouble();
double y = random.nextDouble();
if (x * x + y * y <= 1) {
hits++;
}
}
return (double) hits / ITERATIONS * 4;
}
static double monteCarloFunctional(boolean parallel) {
IntStream stream;
if (parallel) {
stream = IntStream.range(0, ITERATIONS).parallel();
} else {
stream = IntStream.range(0, ITERATIONS);
}
int hits = stream
.map(iteration -> {
var random = ThreadLocalRandom.current();
double x = random.nextDouble();
double y = random.nextDouble();
return x * x + y * y <= 1 ? 1 : 0;
})
.sum();
return (double) hits / ITERATIONS * 4;
}
}
Monte Carlo imperative: best time 3183 ms
Monte Carlo functional single-threaded: best time 3205 ms
Monte Carlo functional multi-threaded: best time 473 ms
Функциональный стиль не проигрывает императивному для однопоточного кода (но это у меня получилось не с первого раза, думаю, что в общем случае проигрывает) и выигрывает примерно в 7 раза при использовании 8-ядерного процессора.