Java - оптимизация типа SAM - PullRequest
       10

Java - оптимизация типа SAM

7 голосов
/ 16 августа 2011

A рабочий документ , описывающий состояние В Project Lambda упоминаются так называемые типы SAM (единственный абстрактный метод). Насколько я знаю, текущее лямбда-предложение не влияет на время выполнения только на компилятор, делая возможным автоматическое преобразование лямбда-выражений в эти типы.

Я думаю, что в идеальных случаях экземпляры типов SAM могут быть внутренне представлены указателями функций. Поэтому JVM может избежать выделения памяти для этих экземпляров.

Мне интересно, способны ли современные виртуальные машины обеспечить такую ​​оптимизацию?

Ответы [ 2 ]

6 голосов
/ 19 августа 2011

@ Tamás Вероятно, вам следует прочитать это сообщение в списке рассылки Брайана Гетца:

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003877.html

По сути, лямбда-абстракция в настоящее время реализована с использованием объектов. Тем не менее, он был разработан, чтобы разрешить альтернативные реализации лямбд, которые были бы «меньше», чем экземпляры классов.

Вы можете думать о ситуации как о похожей на автобокс: целые числа упакованы в Integer, но имеют "меньшее" представление (в виде целых чисел).

В настоящее время лямбды должны быть упакованы в экземпляры типов SAM, потому что JVM в настоящее время не имеет возможности представлять лямбду с какой-либо меньшей конструкцией. В будущем может появиться новый стандарт JVM, который включает «примитивные функции», которые могут представлять лямбда-выражения как нечто иное, чем объекты.

Итак, чтобы ответить на ваш вопрос, тип оптимизации, который вы предлагаете выше, может быть возможен, но он, вероятно, будет сопровождаться работой после «Java 8» над «примитивными функциями», а не специфической для реализации функцией.

5 голосов
/ 17 августа 2011

Нет ничего сложного в преобразовании классов одного метода в указатели на функции, но вы упускаете одну вещь: лямбда-выражения - это не просто функции, они замыкания . Разница в том, что замыкания могут захватывать внешние переменные. Рассмотрим следующий пример в псевдо-Java:

public Adder makeAdder(double startNumber) {
    return #{ int number -> number + startNumber}
}

...

int startNumber = 5; 
Adder add5 = makeAdder(startNumber);
add5.invoke(4);  // ==> 9 

В этом примере лямбда-функция, созданная вызовом makeAdder (), ссылается на переменную, определенную вне этой лямбды. Вот почему это называется «замыкания» - они «закрываются» по своим свободным переменным (в данном случае - по startNumber). Для обработки таких ситуаций замыкания должны содержать как указатель на функцию, так и указатель на ее окружение . Итак, вы получаете некоторую структуру данных, которая имеет метод и хотя бы одну переменную. Но разве это не определение объекта в ООП? Так в чем же причина создания нового вида объектов, если вы можете сделать его экземпляром анонимного класса?

Тем не менее, могут быть выполнены некоторые другие оптимизации для таких анонимных классов. В рабочем документе, на который вы указали, упоминаются некоторые из них, например, вывод и эффективное использование конечных переменных (хотя это делается главным образом для того, чтобы разрешить лямбда-выражения в JVM в принципе, а не для оптимизации кода). Созданный анонимный класс также может быть сделан финальным, и большинство JVM уже имеют хорошие оптимизации для финальных переменных и классов.

Другие улучшения могут также касаться ссылок на окружающую среду - там множество вариантов.

...