Java Lambda性能与声明的供应商/功能

时间:2018-11-06 14:29:14

标签: java performance memory-management

我开始学习如何在Java8中使用Optional进行开发。可能是在这里有记录,但是我一直在使用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)他们是否因为arg值相同而以某种方式被“缓存”了?

编辑

通过观看Does a lambda expression create an object on the heap every time it's executed? ,我了解到我的一流行为得到了回答。由于没有局部变量,它将创建一个单例(至少是oracle jvm)

但是,我不认为该答案可以提供准确的信息来回答我的2)和3)

1 个答案:

答案 0 :(得分:1)

这两种方法之间的区别是您正在重用供应商,这将重用对象,从而节省了一些内存。您需要注意的是可能存在线程问题。由于您使用的是相同的内存,因此需要确保不同的线程不要尝试使用同一对象。

所以回答您的问题:

1。)是,但是您可能还有其他问题。

2。)与第一个问题相同吗?您正在重用Function的实例。这不是您应该在这种情况下使用Function的方式。

3。)它被“缓存”,因为该函数的实例被重用。

通常来说,我会远离您的第二选择,除非被称为1000 /秒,否则您要交易的是增加的复杂性,而这不会转化为明显的性能。

如果您对性能表现感兴趣,请编写一个单元测试,在不同的线程上多次调用此测试,并使用探查器监视运行情况。