gpt4 book ai didi

java - 为什么在给 ArrayList 初始容量时会变慢?

转载 作者:IT老高 更新时间:2023-10-28 20:53:30 24 4
gpt4 key购买 nike

为了一个实验,我做了这个小程序。它只是生成 1000 万个随机字符串并将它们添加到数组列表中。请注意,arraylist 没有具有初始容量。

// editors note: added the necessary boilerplate to run,
// and take initial capacity as an optional cmdline arg for easier testing
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class ArrayListTest {
public static void main(String[] args)
{
int initsize = -1;
if (args.length > 0) {
initsize = Integer.parseInt(args[0]);
}

long startTime = System.currentTimeMillis();

List<String> randNums = initsize>=0 ? new ArrayList<>(initsize) : new ArrayList<>();
// final List<String> randNums = initsize>=0 ? new ArrayList<String>(initsize) : new ArrayList<String>();

Random r = new Random(1);

for (int i = 0; i < 10_000_000; i++) {
final int randomNum = r.nextInt();
randNums.add(Integer.toString(randomNum));
}

System.out.println(System.currentTimeMillis() - startTime);
}
}

我跑了5次,ms的结果是:

8917
8720
7814
8768
8867

然后我修改了程序给 ArrayList 一个初始容量:

    List<String> randNums = new ArrayList<>(10_000_000);

我又跑了 5 次,结果如下:

11562
10454
10499
10481
10415

它肯定一直变慢。我认为情况正好相反,因为通过声明足够大的初始大小,我消除了 ArrayList 增加自身容量的所有开销。为什么速度变慢了?

更多信息:Jre 1.8.051,64 位(在 Windows 10 上);

最佳答案

你会认为它是相反的,但它与垃圾收集有关。

我没有看到您所做的大差异(3900 与 5100),但由于这与 GC 相关,您可能正在使用较低的内存运行。我用 64 位和 -Xmx4g 运行。

打开 GC 日志(-Xloggc:path\to\file.log),我得到这个没有大小:

Java HotSpot(TM) 64-Bit Server VM (25.51-b03) for windows-amd64 JRE (1.8.0_51-b16), built on Jun  8 2015 18:03:07 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 33478384k(25822824k free), swap 33476532k(26121788k free)
CommandLine flags: -XX:InitialHeapSize=535654144 -XX:MaxHeapSize=4294967296 -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
0.188: [GC (Allocation Failure) 131584K->114906K(502784K), 0.0795857 secs]
0.358: [GC (Allocation Failure) 246490K->229080K(634368K), 0.0794026 secs]
0.631: [GC (Allocation Failure) 492248K->452871K(716288K), 0.1389293 secs]
0.770: [Full GC (Ergonomics) 452871K->451407K(1188864K), 3.3224726 secs]
4.270: [GC (Allocation Failure) 714575K->714179K(1271808K), 0.2607092 secs]
4.531: [Full GC (Ergonomics) 714179K->814K(1050624K), 0.0070693 secs]

我得到这个尺寸:

Java HotSpot(TM) 64-Bit Server VM (25.51-b03) for windows-amd64 JRE (1.8.0_51-b16), built on Jun  8 2015 18:03:07 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 33478384k(25818308k free), swap 33476532k(26123684k free)
CommandLine flags: -XX:InitialHeapSize=535654144 -XX:MaxHeapSize=4294967296 -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
0.171: [GC (Allocation Failure) 131584K->129070K(502784K), 0.0919490 secs]
0.370: [GC (Allocation Failure) 260654K->261166K(634368K), 0.4433150 secs]
0.813: [Full GC (Ergonomics) 261166K->260351K(899072K), 1.4135289 secs]
2.460: [GC (Allocation Failure) 523519K->524487K(899072K), 0.7901689 secs]
3.250: [Full GC (Ergonomics) 524487K->523517K(1421312K), 2.3177831 secs]

因为第二次运行最初分配了更多的内存,所以 GC 运行变得更慢。这显然超过了在列表调整大小时进行的额外数组复制。

关于java - 为什么在给 ArrayList 初始容量时会变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32302791/

24 4 0