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

Java Lambda性能与声明的供应商/功能,java,performance,memory-management,Java,Performance,Memory Management,我开始学习如何在java8中使用Optional进行开发。这可能是有文件记载的,但我一直在使用谷歌,没有准确的结果 对于orElseGet方法,我有不同的可能实现,我不确定java在某些情况下是否能更好地处理内存,或者它是否基本相同 假设我在一个类中有一个定义了可选的方法: class myClass { final static private Supplier<Object> MY_SUPPLIER = () -> new Object(); private v

我开始学习如何在java8中使用
Optional
进行开发。这可能是有文件记载的,但我一直在使用谷歌,没有准确的结果

对于
orElseGet
方法,我有不同的可能实现,我不确定java在某些情况下是否能更好地处理内存,或者它是否基本相同

假设我在一个类中有一个定义了
可选
的方法:

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);
  }
}
在这种情况下,根据参数,每次返回不同的供应商

2) java在这里也有更好的内存管理吗

3) 它们是否会以某种方式为具有相同值的arg“缓存”

编辑

通过观看,我明白我的第一流行为得到了回答。由于没有局部变量,它将创建一个单例(至少是oracle jvm)


然而,我觉得这个答案并不能提供准确的信息来回答我的2)和3)

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

因此,要回答您的问题:

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

2)与第一个问题相同吗?您正在重用函数的一个实例。在这种情况下,您不应该这样使用函数

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

一般来说,我会远离你的第二个选择,除非这被称为1000/秒,你交易的复杂性增加了,这不会转化为显著的性能


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

链接答案的可能重复说明,不同的JVM如何处理lambda缓存并没有很好的定义(更改原始方法以在选项中返回对象,以避免JIT优化。由于myMethod2添加了一个额外的函数调用以获取供应商,因此lambda的性能稍好一些。lambda:average=51069619;supplier:average=73730204(纳秒)@littleLouito您不能认真地使用单元测试或类似测试进行基准测试。有太多的JIT优化,无法正确处理它们。如果您想知道代码在“现实”(服务器上长时间运行的进程)中的执行情况,请使用。@maaartinus我使用了一个测试来包装代码,我可以在main()中完成方法。我已经重复了每个方法1.000.000次,其中50.000次作为预热,孤立地测量每个调用。向消费者提供从方法返回的值,以便JIT不会避免任何事情。我确信测试缺少很多东西,但作为一种方法,它可以help@littleLouito你所做的听起来是对的,但可能不是。例如,你的消费者是否真的使用了价值,并用它做了一些无法优化的事情?如果是这样,那么它可能比你想要测量的要花费更多的时间。你能确定,你做得对吗?JMH的黑洞做了这项工作,它相当复杂。无论如何,我只是想让你意识到这个问题(Java基准测试比大家预期的要困难得多)和标准解决方案(JMH),仅此而已。@maaartinus我了解JMH,我也读过微基准测试。这就是为什么我说我的测试可能做得不好的原因。但这是我在五分钟内就能做到的:)谢谢你的评论。我喜欢这段对话显示出做好微基准测试有多么困难
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));
  }
}