我正在研究原始集合庫Banana,它支持原始linked lists。 您的使用案例幾乎是香蕉發光的理想用例,但它可以做更多的事情(包括可變長度塊,您未使用但可能在現實世界中使用)。
這是該基準測試我的電腦上的結果:
Banana : 1269 ms elapsed
Banana : total: 2.5 GB, free: 0.5 GB, used = 2.1 GB, Banana reports that it's actually using 2.1 GB
Java : 13543 ms elapsed
Java : total: 6.2 GB, free: 2.0 GB, used = 4.2 GB
你可以看到,香蕉更快,佔用更少的內存。 (Java的內存將是,如果你本身運行的更好,但不運行香蕉函數首先
Java : 14426 ms elapsed
Java : total: 5.8 GB, free: 1.9 GB, used = 3.9 GB
但仍然沒有香蕉附近的任何地方。
package net.yadan.banana.list;
public class LinkedListBenchmark {
public static void main(String[] args) {
banana();
java();
}
public static void banana() {
long t = System.currentTimeMillis();
// initial list size 16m records, block size 32 (storage is int[], so we
// need 32 ints to hold 16 longs)
net.yadan.banana.list.LinkedList list = new LinkedList(16 * 1024 * 1024, 16 * 2, 0);
// initial fill in
for (int i = 0; i < 16L * 1024 * 1024; i++) {
list.appendTail(32); // similar to java list.add() which appends to the
// end of the list
}
// the main stuff
for (int i = 0; i < 16L * 1024 * 1024; i++) {
list.removeHead(); // similar to java list removeFirst()
list.appendTail(32); // similar to java list.add() which appends to the
// end of the list
}
System.out.println("Banana : " + (System.currentTimeMillis() - t) + " ms elapsed");
float GB = 1024 * 1024 * 1024;
long total = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
System.out
.printf(
"Banana : total: %5.1f GB, free: %5.1f GB, used = %5.1f GB, Banana reports that it's actually using %5.1f GB\n",
total/GB, free/GB, (total - free)/GB, list.computeMemoryUsage()/GB);
}
public static void java() {
long t = System.currentTimeMillis();
java.util.LinkedList<long[]> list = new java.util.LinkedList<long[]>();
// initial fill in
for (int i = 0; i < 16L * 1024 * 1024; i++) {
list.add(new long[16]);
}
// the main stuff
for (int i = 0; i < 16L * 1024 * 1024; i++) {
list.removeFirst();
list.add(new long[16]);
}
System.out.println("Java : " + (System.currentTimeMillis() - t) + " ms elapsed");
float GB = 1024 * 1024 * 1024;
long total = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
System.out.printf("Java : total: %5.1f GB, free: %5.1f GB, used = %5.1f GB\n", total/GB, free/GB,
(total - free)/GB);
}
}
您可以用-XX發表您的GC日誌:+ PrintGCDetails? –
6GiB情況下插入的頻率和隊列長度是多少? –
您正在快速生成垃圾,不僅僅是列表元素,而是'long [16]'塊,它們可能比列表元素大。他們需要收集。你只是想更頻繁地做少量的GC嗎? –