为什么是java varargs数组

问题描述 投票:0回答:1

最近我遇到了一种情况,在java中使用可变参数是合乎逻辑的。然后我发现可变参数只是数组的语法糖,并且对它所暗示的性能影响感到好奇。我读了一点关于它的内容,发现了几篇文章,并且可以放心地假设,它比使用普通参数慢。我还遇到过像 EnumSet.of(...) 这样的方法,它们具有 5 种不同的重载,以避免由于性能原因而必须使用可变参数。不过我不是来谈论这个的。我很好奇的是为什么它们首先被实现为数组。

例如,在 C++ 中,您有参数包,但它们不是数组。这有什么历史原因吗?

编辑:似乎有一些关于性能的讨论正在进行。我想再次澄清:我没有对任何东西进行基准测试。我提到性能问题是因为即使在 JDK 中,它们似乎也存在,在某些情况下,有些代码会使用可变参数来提高性能。而且,性能并不是将可变参数实现为数组的唯一限制。例如,您不能使用 java varargs 做的另一件事是将参数转发给另一个函数,或者换句话说 - 解压它们。

java variadic-functions
1个回答
0
投票

归根结底,它使语言规范保持简单,使语言实现保持简单,同时它的成本并不高,因为内存分配(即分配一个数组来保存参数)非常快在爪哇。

首先,在 Java 诞生的时候,C++ 中还不存在参数包,所以我们不要拿苹果和橘子进行比较:我们必须将 java 可变参数与旧的 C 风格可变参数进行比较。

请注意,使用旧的 C 风格可变参数,您无法将变量参数转发给另一个函数。所以把它从照片中去掉。

现在,使可变参数在 C 中成为可能的原因之一是,任何函数实际上都可以使用任意数量的参数来调用,并且这不会导致崩溃,因为调用者知道它们有多少个参数压入堆栈,谁负责在函数返回时将它们从堆栈中弹出。 x86 中的 C 函数调用看起来(或过去看起来)像这样:

push arg1 ;4 bytes
push arg2 ;4 bytes
call function
add sp, 8

这代表了性能损失:C 中的每个函数调用都必须遵循

add sp, <value>
指令。 (除非该函数不接受任何参数。)我一直认为这是迟钝的。

在 Java 中,他们决定每个函数都有许多固定的参数。因此,他们可以让函数而不是调用者负责从堆栈中弹出参数。 在 x86 中,这样做是这样的:

ret 8 ;return, popping 8 bytes from the stack.

这是一个更好的语言架构选择。不幸的是,这似乎意味着该语言不能有可变参数。

嗯,当然可以,通过使用单个数组来实现它们。

这个轮子已经被发明了,为什么不重复利用呢?

© www.soinside.com 2019 - 2024. All rights reserved.