Pull to refresh

Comments 36

В JDK 8 лямбда-выражения будут реализованы уже на уровне компилятора и будут преобразовываться в байткод еще на этапе компиляции, поэтому теоретически производительность такого кода должна быть выше.
Не очень понятно. А в остальных озвученных проектах они что, на этапе выполнения что ли транслируются и выполняются? O_o Очевидно же, что и в JDK8 лямбды и прочее — всего лишь сахар и развернутся на этапе компиляции в какие-нибудь обычные существующие конструкции, в этом же виде они и будут представлены байт-кодом. В случае лямбд, емнип, это будут просто статические методы.
Вот, собственно, в этой презентации в частности про проект лямбда вкратце сказано: cr.openjdk.java.net/~jrose/pres/201204-LangNext.pdf
А в остальных озвученных проектах они что, на этапе выполнения что ли транслируются и выполняются?

В случае LambdaJ это так, собственно поэтому эта библиотека оказалась самая медленная.
А, ну ок. Я не пользовался LambdaJ, могу ошибаться, но судя по коду
final int age = Lambda.min(forEach(select(db.getSales(), having(on(Sale.class).getCost(),
                    greaterThan(50000.00)))).getBuyer(), on(Person.class).getAge());
всё же не транслируется уж наверно на этапе выполнения, просто через рефлекшен работает.
> Очевидно же, что и в JDK8 лямбды и прочее — всего лишь сахар и развернутся на этапе компиляции в какие-нибудь обычные существующие конструкции

Вообще-то не очевидно. Если я не ошибаюсь, на некотором этапе разработки спецификации JDK7/8 обсуждался вариант модифицировать байт-код JVM таким образом, чтобы были возможны настоящие замыкания переменных на стеке(в текущей реализации всех этих гуав замыкание происходит через кучу).
UFO just landed and posted this here
хотелось бы узнать, зачем в реализации лямбда-выражений опираться на динамические узлы вызовов?
ведь после компиляции, по-моему, модифицированный «компилятор» должен сгенерировать идентичный код, как если бы это происходило на этапе компиляции.

>Это даст возможность генерировать оптимальный код для лямбд уже после javac-компиляции

я так понимаю, что лямбды являются статически типизированными с сильной типизацией, тогда что может дать динамизм?
UFO just landed and posted this here
UFO just landed and posted this here
Замечания конструктивные.

  1. Согласен, вообще iterable, guava и jdk8 в большинстве тестов дают результаты очень близкие
  2. Это я поправлю
  3. Увы, все тесты запускались в одной JVM, исходник тут
  4. Усреднился
UFO just landed and posted this here
А функциональный стиль разбрасывается по ядрам или в один поток фигачит?
В данных тестах в один поток. В JDK 8 заложены возможности вызывать некоторые вещи параллельно, например в интерфейсе List появился метод parallelSort

public void parallelSort(Comparator<? super E> c) default {
    Collections.<E>sort(this,c);
}
Вот например код:
final int age = db.getSales()
                    .filter((Sale sale)->sale.getCost() > 50000.00)
                    .<Integer>map((Sale sale)->sale.getBuyer().getAge())
                    .reduce(0, (x,y)-> x<y ? x : y);

сейчас он шпарит (и будет шпарить) в один тред.
Но! Будет магический метод parallel (еще не сделан), и можно будет написать так:
final int age = db.getSales()
                    .parallel()
                    .filter((Sale sale)->sale.getCost() > 50000.00)
                    .<Integer>map((Sale sale)->sale.getBuyer().getAge())
                    .reduce(0, (x,y)-> x<y ? x : y);
а можно так:
final int age = db.getSales()
                    .filter((Sale sale)->sale.getCost() > 50000.00)
                    .parallel()
                    .<Integer>map((Sale sale)->sale.getBuyer().getAge())
                    .reduce(0, (x,y)-> x

Тогда фильтр последовательный, а мап и редьюс параллельные.
Было бы интересно добавить в сравнение другие JVM языки с lambda, например Scala
Тест «Index cars by brand» похоже некорректен.
Guava заметно отстает от Iterative и если посмотреть на код теста, то в версии для Guava вместо Map<String, Car> используется ImmutableListMultimap<String, Car>, который хранит для ключа коллекцию значений. Возможно в этом и причина отставания.
Да, вероятно вы правы. У меня не получилось сделать Guava реализацию полностью идентичной.
Результат теста исходя из названия должен возвращать что-то вроде Map<String, Iterable<Car>>. Для Guava это соблюдается, для остальных вариантов одному бренду будет соответствовать только одна машина. Предлагаю либо исключить этот тест, либо написать правильные реализации для других вариантов. Сейчас он не дает объективного сравнения.
Вас не смущает, что в тесте на самую крупную сделку, в официальном тесте по ссылке разница производительности в 3 раза, а у вас — в 15?
Да, это смущает, я специально несколько раз проверял результаты вычислений и не нашел никаких изъянов.
Петька, приборы?
Что означают числа в таблицах?
И когда компиляете тест для JDK8 lambda — поставте javac ключик: -XDlambdaToMethod
впрочем, тут я спешу. Может и хватит. Но надо доказать, что хватит.
UFO just landed and posted this here
не мешайте, сэр. У меня можно сказать ломка на отдыхе, а тут тааакое ;)
UFO just landed and posted this here
мм, я так понимаю, это междусобойчик программистов из oracle? добрый вечер всем, добро пожаловать на вечеринку
Сейчас, я ни за что не ответственный. ;) Я в отпуске. ;)
Кстати, а лямбды то тут причем? ;) Сравнивается то, что называется «collections bulk operations». :)
вы правы, можно было и без лямбд обойтись
Кстати, это плохо:
final int age = Collections.min(db.getSales()
                    .filter((Sale sale)->sale.getCost() > 50000.00)
                    .<Integer>map((Sale sale)->sale.getBuyer().getAge())
                    .into(new ArrayList<Integer>()));


Надо:
final int age = db.getSales()
                    .filter((Sale sale)->sale.getCost() > 50000.00)
                    .<Integer>map((Sale sale)->sale.getBuyer().getAge())
                    .reduce(0, (x,y)-> x<y ? x : y);



Я бы даже сказал как-то так:
final int age = db.getSales()
                    .filter(sale->sale.getCost() > 50000.00)
                    .mapToInt(sale->sale.getBuyer().getAge())
                    .min()
                    .orElse(0);

(сорри за некропост)
Sign up to leave a comment.

Articles