【问题标题】:Java Function Pointers and AutoboxingJava 函数指针和自动装箱
【发布时间】:2021-04-16 14:22:53
【问题描述】:

据我所知,Java 函数指针或 lambdas 声明签名如下:

BiFunction<Integer, Integer, Integer> add = (a,b) -> a+b;

要应用它,我们使用:

add.apply(1,2)

这里涉及到自动装箱吗?
如果是,如何避免它(并且仍然有类似于函数指针的东西)?

我知道自动装箱可能是一个性能问题,因为它每次都会创建一个对象(而不是堆栈上的一个原语)。 如果它隐含地发生,这可能会令人沮丧,所以我问。

【问题讨论】:

    标签: java function lambda


    【解决方案1】:

    这里涉及到自动装箱吗?

    当然。 1int 文字,而不是 Integer。因此,为了传递给期望 Integer 的东西,编译器在幕后做了必要的事情。

    正如 cmets 中所指出的:如果您想完全避免这种情况,则需要改用 IntFunction。因为该抽象允许您传递 int 值。

    或者,您可以明确表示 ...apply(Integer.valueOf(1), ...

    【讨论】:

      【解决方案2】:

      Function&lt;Integer, Integer&gt; add = (a,b) -&gt; a+b;

      你很困惑;这不编译。 Function&lt;Integer, Integer&gt;一个整数引用变成另一个;您所写的内容将 两个 引用转换为另一个。我假设你的意思是例如:

      BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
      

      这里涉及到自动装箱吗?

      是的。

      我知道自动装箱可能是性能问题,因为它每次都会创建一个对象(而不是堆栈上的原语)如果它隐式发生,这可能会令人沮丧,所以我问;)

      你忘记了表现的黄金法则。

      你那微不足道的人脑无法理解这里发生的深度和互动。这不是我在侮辱你:这就是即使是从事 JVM 优化例程的工程师自己也公开提倡的要点:在 CPU 缓存、管道、操作系统优化、幽灵重写和热点之间 - 你不知道 .

      在看代码并指着它说时,只有两个合理的立场:这是低效的,应该重写。

      • 您查看算法并意识到算法的复杂性是不必要的复杂。例如,您查看一些排序代码并意识到它是冒泡排序而不是更优化的快速排序(即 O(n log n) 算法可用,但您正在查看的代码比这更糟)。

      • 您有一个分析器报告和一些基于似是而非的现实数据的结果 两者:我们有一个性能问题,并且这是 1% 的代码CPU 将 99% 的时间都花在了上面。

      还有什么,比如这种随意的“我听说自动装箱很糟糕”?一个严重的错误。不要因为这样的原因重写代码。您通常字面上节省了 0 纳秒的性能。当您真正面临性能问题和分析器报告告诉您需要查看哪 1% 的代码时,您通常需要重写部分,这意味着您需要 所有代码项目要整洁、灵活、易于测试和足够抽象,以便于例如重新键入流入和流出分析器告诉您的关键路径的数据。通常,“重写因为某些性能白痴指南是这样说的”会使您的代码 less 抽象和 less 灵活,从而损害性能。因为如果出现关键路径,重写将更加困难,而重写关键路径是对代码库的唯一更改,会对性能产生有意义的影响。

      如果是,如何避免自动装箱(仍然有类似于 fkt-pointers 的东西?)

      BiFunction 不是正确的类型。对于初学者来说,这更像是一个运算符(不同之处在于,一个函数可以例如将整数和字符串转换为输入流,运算符仅对相同的类型进行操作:例如,所有整数)。一些原语的功能接口有专门的案例。

      因此,你真正想要的也许是:

      IntBinaryOperator add = (a, b) -> a + b;
      

      【讨论】:

      • BiFunction 的签名是BiFunction&lt;Integer, Integer, Integer&gt;,尽管在这种情况下BinaryOperator&lt;Integer&gt; 绝对是更可取的。
      猜你喜欢
      • 1970-01-01
      • 2011-01-19
      • 2018-06-20
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多