Java中的toArray与stream.toArray有什么性能差异
我需要将ID列表转换为ID数组. 我可以用很多方法做到这一点,但不确定应该使用哪种方法.
I need to convert a list of ids to array of ids. I can do it in many ways but not sure which one should be used.
说
1. ids.stream().toArray(Id[]::new)
2. ids.toArray(new Id[ids.length])
哪个效率更高?为什么?
Which one is more efficient and why?
java-11引入了具有以下实现的Collection::toArray
:
java-11 introduced Collection::toArray
that has this implementation:
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
实际上,这样做是为了简化您的情况:ids.toArray(new Id[0])
;即-它没有指定预期的总尺寸.
To make it simpler in your case, it is actually doing : ids.toArray(new Id[0])
; that is - it is not specifying the total expected size.
这比指定大小要快,而且不直观;但与以下事实有关:如果JVM可以证明正在分配的数组将被紧随其后的某些复制所覆盖,则它不必对数组进行初始置零,而事实证明是然后指定初始尺寸(必须归零的地方)更快.
This is faster than specifying the size and it's non-intuitive; but has to do with the fact that if the JVM can prove that the array that you are allocating is going to be overridden by some copying that is immediately followed, it does not have to do the initial zeroing of the array and that proves to be faster then specifying the initial size (where the zeroing has to happen).
流方法将具有(或尝试猜测一个估计值)流内部将要计算的初始大小,因为:
The stream approach will have (or try to guess an estimate) an initial size that the stream internals will compute, because:
ids.stream().toArray(Id[]::new)
实际上是:
ids.stream().toArray(size -> Id[size]);
根据Spliterator
具有的内部特性,
并且size
是已知的或估计的.如果流报告了SIZED
特征(就像您的简单情况一样),那么很容易就知道size
.另一方面,如果不存在此SIZED
,则流内部将仅估计将存在多少个元素,在这种情况下,将使用隐藏的新集合来捕获称为SpinedBuffer
的元素.
and that size
is either known or estimated, based on the internal characteristics that a Spliterator
has. If the stream reports SIZED
characteristic (like in your simple case), then it's easy, size
is always known. On the other hand if this SIZED
is not present, stream internals will only have an estimate of how many elements will be present and in such a case, an hidden new collection will be used to capture elements, called SpinedBuffer
.
您可以在此处了解更多信息,但是方法ids.toArray(new Id[0])
将可以最快.
You can read more here, but the approach ids.toArray(new Id[0])
will be the fastest.