TAG | performance
http://www.javalobby.org/articles/google-collections/
http://code.google.com/p/google-collections/
原來 Google 也有以 Apache License 推出的 collection library。
讀了一下上文和它的 API ,的確是一套不錯的 collection framework
- 它以 Java 5 為目標,不像其他已流行的 library 為了向 1.4 相容而浪費 Java 5 的 Generic Type
- 有很多常用實用而卻沒有通用的元件,例如 MultiMap 和 Join
- 以 Apacle Style Licnse 2.0 發佈,應用起來沒有版權的問題
- It is Google
- 可惜就是還太早了,還是 0.5(alpha)。也就是可能到能流行之前可能會有大改動。
看到這篇 Erlang Ring Benchmark – 桃之夭夭 – BlogJava 然後寫了這個
package net.hkdennis2k;
public final class RingBenchmark extends Thread {
static final ThreadGroup tg = new ThreadGroup("g");
static final int n = Integer.getInteger("n", 100);
static final int m = Integer.getInteger("m", 90000);
static long startTime;
private int msg = -1;
private final RingBenchmark next;
private final int id;
public RingBenchmark(final int id, final RingBenchmark next) {
super(tg, Integer.toString(id));
this.next = next;
System.out.println(this.id = id);
start();
}
@Override
public final void run() {
try {
if (id == 0)
run1();
else if (next == null)
run3();
else
run2();
} catch (InterruptedException e) {
}
}
private final synchronized void run2() throws InterruptedException {
while (msg != 0) {
wait();
next.notify(msg);
}
}
private final synchronized void run3() throws InterruptedException {
while (msg != 0)
wait();
System.out.println(System.currentTimeMillis() - startTime);
}
private final synchronized void run1() throws InterruptedException {
while (msg != 0) {
wait();
next.notify(msg);
synchronized (RingBenchmark.class) {
RingBenchmark.class.notify();
}
}
}
public synchronized static void main(String[] args)
throws InterruptedException {
tg.setMaxPriority(Thread.MIN_PRIORITY);
RingBenchmark firstThread = new RingBenchmark(n - 1, null);
while (firstThread.id > 0)
firstThread = new RingBenchmark(firstThread.id - 1, firstThread);
for (RingBenchmark r = firstThread; r != null; r = r.next)
r.start();
System.out.println("Start:" + tg.activeCount());
startTime = System.currentTimeMillis();
for (int i = m - 1; i >= 0; i--) {
firstThread.notify(i);
RingBenchmark.class.wait();
}
}
private final synchronized void notify(int i) {
msg = i;
notify();
}
}
速度上還可以,沒有那位人兄說的 “效率大约能差到百倍”。
在 Pentium 4 3.0Ghz HT WinXP JRE 1.6 下直接執行 n=100, m=90000,只要約 4.5秒 (+-0.3)。
可惜 -Xss 不能設得比 1k 更細,所以試不到那個另外 10000 條 thread 的測試。
在嘗試簡化和優化的過程中,發現了幾件有趣的事。
- 把 Thread 的 priority 設得越低,結果越快;MIN_PRIORITY 比 default 快一倍。
- 如果更改 start() 的位置和方式,有可能會嚴重影嚴執行效率(就算它不在 ring 當中),而其影響力十分大,足以令結果相差兩倍甚至百倍。例如:
- 把 for loop start 改為 start 的 recursive 方式
- 先 Constructor 中執行 start()
- ThreadGroup 好像好似解決 (2.1) 所引起的問題(未確定)
- 根據 javaspecialists,直接 extends Thead 會比 Runnable 快一點點,但我試不出來。
