Java 内部函数与外部(静态)方法

Java 内部函数与外部(静态)方法,java,performance,Java,Performance,我有这个: 第1版: public Map<String, Float> getMap() { var map = new HashMap<String, Float>(); // puts v in map if v is not null final BiConsumer<String, Float> put = (k, v) -> { if (v != null) map.put(k, v); };

我有这个:

第1版:

public Map<String, Float> getMap() {
    var map = new HashMap<String, Float>();

    // puts v in map if v is not null
    final BiConsumer<String, Float> put = (k, v) ->
    {
    if (v != null) map.put(k, v);
    };

    put.accept("Ted", 1f);
    put.accept("Mike", 2f);
    // .. other entries

return map;

}
publicmap getMap(){
var map=newhashmap();
//如果v不为null,则将v放入映射中
最终双消费者投入=(k,v)->
{
如果(v!=null)map.put(k,v);
};
放置。接受(“Ted”,1f);
放置。接受(“Mike”,2f);
//…其他条目
返回图;
}
以上工作。但是,以下解决方案比版本1快得多

第2版:

public Map<String, Float> getMap() {
    var map = new HashMap<String, Float>();
    put(map, "Ted", 1f);
    put(map, "Mike", 2f);
    // .. other entries

return map;

}

static <K,V> void put(Map<K, V> map, K k, V v){
    if (v != null) map.put(k, v);
}
publicmap getMap(){
var map=newhashmap();
放置(地图“Ted”,1f);
放置(地图,“麦克”,2f);
//…其他条目
返回图;
}
静态空放(映射图、K、V){
如果(v!=null)map.put(k,v);
}
比较ns(取决于put调用的数量):

  • 版本1:Diff:390.801
  • 版本2:Diff:31.554
因此,与版本2(只使用静态方法将值放入映射)相比,版本1中似乎存在开销(创建和调用这些内部函数)


我的问题是:内部
函数
(在一个方法中)通常比使用外部(静态)方法慢吗?

我认为,你在比较两个无与伦比的东西

意味着:用一个不匹配且更耗时的功能来证明lambda的速度会慢很多,这是值得怀疑的。
用于比较的使用者版本甚至没有相同的参数列表

第3版:

public Map<String, Float> getMap() {
    // puts v in map if v is not null
    final TriConsumer<Map<String,Float>, String, Float>
      putter = (m, k, v) -> { if (v != null) m.put(k, v); };

    var map = new HashMap<String, Float>();
    putter.accept(map, "Ted", 1f);
    putter.accept(map, "Mike", 2f);
    // .. other entries
    return map;
}
publicmap getMap(){
//如果v不为null,则将v放入映射中
最终三角消费者
推杆=(m,k,v)->{if(v!=null)m.put(k,v);};
var map=newhashmap();
推杆接受(图“Ted”,1f);
推杆。接受(图,“麦克”,2f);
//…其他条目
返回图;
}


出现计时问题不是因为lambda使用者是在方法内部或外部定义的,而是因为使用了错误的使用者。
(希望基准测试专家能够确认这一事实。)

它们不是等价的。第一个版本将空检查应用于所有
put()
操作。第二个只适用于一个。@user207421您说“您正应用一个空检查”。你说的话很烦人,我不明白。我对每个put调用(两个版本)进行“null”检查。并且在两个版本中生成的映射是相同的。@user207421 OP在第一个版本中没有使用匿名内部类。你认为是吗?你能展示一下你是如何测量时间的吗?在我的机器上,使用JMH,我只测量到lambdas的速度慢了不到10%。我认为这可能是因为
accept
是动态调度的……您确实需要使用适当的工具来衡量性能。对JMH的工作做了简要介绍,并应说明原因。@Federico在至少一个相同页面上的统一演示似乎不可取?我不确定我是否理解您的评论。@Federico我想坚持OP问题的格式,因此出于上下文原因,我还用粗体写了第3版。在那里,现在这不再是个问题了。但一般来说,格式应该用来使文章更具可读性,而不是与某人的风格相匹配。@Federico谢谢。即便如此,也应该有一种礼仪。有一些令人毛骨悚然的条目将它们的标题设置为。