Покажите, пожалуйста, профит от функционального программирования.
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 04.08.24 09:57
Оценка: -2 :))
То есть, два примера консольных программ на Java каждая,
в первом случае когда программа написана в императивном стиле (можно с ООП),
а во втором случае, когда эта же самая программа написана в функциональном стиле (с монадами).

Хочу увидеть, как вторая программа сама задействует многоядерность и обгоняет первую в 28 раз (по числу ядер).
Re: Покажите, пожалуйста, профит от функционального программ
От: vsb Казахстан  
Дата: 04.08.24 10:48
Оценка: 4 (1) +1
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-ядерного процессора.
Отредактировано 04.08.2024 11:27 vsb . Предыдущая версия . Еще …
Отредактировано 04.08.2024 11:26 vsb . Предыдущая версия .
Отредактировано 04.08.2024 11:07 vsb . Предыдущая версия .
Отредактировано 04.08.2024 10:53 vsb . Предыдущая версия .
Re: Покажите, пожалуйста, профит от функционального программирования.
От: kov_serg Россия  
Дата: 04.08.24 10:50
Оценка: +2
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>То есть, два примера консольных программ на Java каждая,

ЭФ>в первом случае когда программа написана в императивном стиле (можно с ООП),
В первом случае вы сами явно создаёте потоки выполняете действия, ждёте и собираете результат.
С ООП вы для всего этого еще делаете кучу классов и переходников.

ЭФ>а во втором случае, когда эта же самая программа написана в функциональном стиле (с монадами).

Тут вы говорите что надо сделать, и указываете что не плохо бы разбить на батчи и распараллелить (по числу ядер).

ЭФ>Хочу увидеть, как вторая программа сама задействует многоядерность и обгоняет первую в 28 раз (по числу ядер).

В идеале они должны работать с одинаковой скоростью.
Re[2]: Покажите, пожалуйста, профит от функционального программ
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 04.08.24 11:32
Оценка:
vsb> у меня получилось не с первого раза

Да, лишнее было создание объекта-точки в куче.

Большое спасибо, очень полезный пример. В тысячи раз полезнее второго ответа в теме,
рассуждающего общими словами.
Re[3]: Покажите, пожалуйста, профит от функционального прогр
От: vsb Казахстан  
Дата: 04.08.24 11:35
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

vsb>> у меня получилось не с первого раза


ЭФ>Да, лишнее было создание объекта-точки в куче.


На самом деле нет.


    long hits = stream
        .filter(iteration -> {
          var random = ThreadLocalRandom.current();
          double x = random.nextDouble();
          double y = random.nextDouble();
          return x * x + y * y <= 1;
        })
        .count();


Вот этот код работает в 2.5 раза медленней. Почему — не знаю. Видимо особенности реализации стримов. Вообще Java тут в каком-то плане свинью подкладывает, не самый лучший язык для таких вещей. Предполагаю, что на Rust всё будет гораздо лучше оптимизироваться (но проверять это, конечно, я не буду).
Отредактировано 04.08.2024 11:36 vsb . Предыдущая версия .
Re: Покажите, пожалуйста, профит от функционального программирования.
От: dsorokin Россия  
Дата: 27.08.24 16:58
Оценка:
Файр,

Пол Хьюдак в своей книге "The Haskell School of Music" написал, что

Haskell is quite a bit different from conventional imperative or object-oriented languages such as C, C++, Java, C#, and so on. It takes a different mind-set to
program in such a language, and appeals to the mathematically inclined and to those who seek purity and elegance in their programs.


Яндекс-переводчик дает такой перевод:

Haskell довольно сильно отличается от обычных императивных или объектно-ориентированных языков, таких как C, C++, Java, C# и так далее. Чтобы
программировать на таком языке, требуется иной склад ума, и он подходит как для математиков, так и для тех, кто стремится к чистоте и элегантности в своих программах.


Короче, нравится людям программировать на языках ФП. И не мешайте им! Если кто-то не понимает их, то это проблемы именно тех людей, а не тех, кому нравится ФП. Вот и весь профит!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.