![](/img/trans.png)
[英]What is the fastest way to set an arbitrary range of elements in a Java array to null?
[英]What is the fastest way to fill an ArrayList with null in java?
我想要一个包含 n 组整数的列表,最初这个列表应该用 null 填充。 很多 Set 将在稍后初始化,有些将保留为 null。
我尝试了不同的方法来实现这一点,其中一些包括在这里:
List<HashSet<Integer>> List_of_Sets = Arrays.asList(new HashSet[n]);
ArrayList<HashSet<Integer>> List_of_Sets = new ArrayList<>(n);
while(n-- > 0) List_of_Sets.add(null);
有没有更快的方法来做到这一点?
为澄清起见,arrays 的示例将是Arrays.fill()
曾经比:
/*
* initialize a smaller piece of the array and use the System.arraycopy
* call to fill in the rest of the array in an expanding binary fashion
*/
public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0){
array[0] = value;
}
//Value of i will be [1, 2, 4, 8, 16, 32, ..., len]
for (int i = 1; i < len; i += i) {
System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
}
}
^上面的代码来自罗斯德鲁对设置数组所有值的最快方法的回答?
有没有更快的方法来做到这一点?
据我所知,没有。 当然,没有比这更快的简单方法了。
根据它的工作原理,我认为(但我没有测试过) Arrays.asList(new HashSet[n])
应该是最快的解决方案。
可以实现自定义List
实现,类似于ArrayList
但预初始化为 N null
值。 但在底层,初始化将与asList
返回的List
实现中发生的情况几乎相同。 所以我怀疑任何性能改进都会显着......或者值得付出努力。
如果您想确定这一点,您可以编写各种选项的基准。 但是,在这种情况下,我认为这不是正确的方法。
相反,我建议对整个应用程序进行基准测试和分析,以确定此列表上的操作是否是真正的性能热点。
如果它不是热点,我的建议是只使用Arrays.asList
方法并将时间花在更重要的事情上。
如果是热点,则应考虑将List
替换为数组。 根据您之前的描述,您似乎将List
用作数组; 即使用位置get
和set
操作,并且不使用更改列表大小的操作。 如果是这种情况,那么使用真正的数组应该更有效。 它节省了 memory,并避免了间接级别和(可能)一些边界检查。
不这样做的一个原因是,如果您需要将数组传递给需要List
的其他代码。
如果调整大小对您来说并不重要,那么实现您自己的列表可能会很快。 它也可能是越野车。 与 Java 的列表相比,基准测试至少会很有趣。 您可能会看到一个奇怪的效果,即标准列表可能会更快地被 JIT 优化,因为它们可以被 Java 的标准库在内部使用。
这是我的尝试,尽管我建议您不要使用它。 请改用标准列表实现。
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
Set<Integer>[] arr = new Set[100_000]; // all set to null by default.
List<Set<Integer>> myList = new ArrayBackedList<>(arr);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class ArrayBackedList<T> extends AbstractList<T> {
private final T[] arr;
ArrayBackedList(T[] arr) {
this.arr = arr;
}
@Override
public T get(int index) {
return arr[index];
}
@Override
public int size() {
return arr.length;
}
@Override
public T set(int index, T value) {
T result = arr[index];
arr[index] = value;
return result;
}
}
另一种可能性是实现一个始终为空的、固定大小的列表。 使用它来初始化 ArrayList。 我不会 promise 它很快但你可以试试。
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
List<Set<Integer>> allNull = new NullList<>(100_000);
List<Set<Integer>> myList = new ArrayList<>(allNull);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
System.out.println(myList.size());
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class NullList<T> extends AbstractList<T> {
private int count;
NullList(int count) {
this.count = count;
}
@Override
public T get(int index) {
return null;
}
@Override
public int size() {
return count;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.