Java лямбда-производительность против заявленных поставщиков / функций - PullRequest
0 голосов
/ 06 ноября 2018

Я начинаю учиться, как развиваться с Optional в java8. Возможно, это где-то задокументировано, но я использую Google без точного результата.

У меня есть различные возможные реализации метода orElseGet, и я не уверен, что java улучшает обработку памяти в некоторых случаях, или она почти такая же.

Допустим, у меня есть метод в классе с определением Optional:

class myClass {

  final static private Supplier<Object> MY_SUPPLIER = () -> new Object();

  private void myMethod1 () {
    Optional<Object> x; // somehow Initialized
    Object y = x.orElseGet(() -> new Object());
  }

  private void myMethod2 () {
    Optional<Object> x; // somehow Initialized
    Object y = x.orElseGet(MY_SUPPLIER);
  }
}

С моей скромной точки зрения, эта секунда должна иметь лучшее управление памятью в java, поскольку она объявляется только один раз Supplier и всегда используется одинаково.

1) это правда?

Теперь, давайте пойдем дальше и представим, что нам нужно предоставить разные объекты в зависимости от параметров.

class myClass2 {

  final static private Function<String, Supplier<AnyCustomClass>> MY_SUPPLIER_PROVIDER = (p) -> () -> new AnyCustomClass(p);

  private void myMethod1 (String arg) {
    Optional<AnyCustomClass> x; // somehow Initialized
    AnyCustomClass y = x.orElseGet(() -> new AnyCustomClass(arg));
  }

  private void myMethod2 (String arg) {
    Optional<AnyCustomClass> x; // somehow Initialized
    AnyCustomClass y = x.orElseGet(MY_SUPPLIER_PROVIDER.apply(arg));
  }
}

В этом случае, в зависимости от аргумента, каждый раз возвращается другой поставщик.

2) У java здесь также лучше управление памятью?

3) Они как-то "кэшируются" для аргумента, принимающего одно и то же значение?

EDIT

При просмотре Создает ли лямбда-выражение объект в куче каждый раз, когда оно выполняется? Я понимаю, что мое первоклассное поведение ответили. Поскольку локальных переменных нет, будет создан синглтон (по крайней мере, oracle jvm)

Как бы то ни было, я не чувствую, что этот ответ дает точную информацию для ответа на мои 2) и 3)

1 Ответ

0 голосов
/ 06 ноября 2018

Разница между обоими методами заключается в том, что вы повторно используете поставщика, который будет повторно использовать объекты, что сэкономит вам немного памяти. Здесь нужно быть осторожным с возможными проблемами с потоками. Поскольку вы используете одну и ту же память, вам нужно убедиться, что разные потоки не пытаются использовать один и тот же объект.

Итак, чтобы ответить на ваши вопросы:

1.) Да, но у вас могут быть другие проблемы.

2.) Это так же, как первый вопрос? Вы повторно используете экземпляр функции. Это не то, как вы должны использовать функцию в этом контексте.

3.) Он «кэшируется» в том смысле, что экземпляр функции используется повторно.

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

Если вас интересует, как будет выглядеть производительность, напишите модульный тест, который вызывает его несколько раз в разных потоках и отслеживает выполнение с помощью профилировщика.

...