Dennis' Blog of Indiscriminate | I thought what I’d do was, I’d pretend I was one of those deaf-mutes

TAG | performance

Oct/07

27

Google Collections Library

http://www.javalobby.org/articles/google-collections/

http://code.google.com/p/google-collections/

 

原來 Google 也有以 Apache License 推出的 collection library。

讀了一下上文和它的 API ,的確是一套不錯的 collection framework

  1. 它以 Java 5 為目標,不像其他已流行的 library 為了向 1.4 相容而浪費 Java 5 的 Generic Type
  2. 有很多常用實用而卻沒有通用的元件,例如 MultiMap 和 Join
  3. 以 Apacle Style Licnse 2.0 發佈,應用起來沒有版權的問題
  4. It is Google
  5. 可惜就是還太早了,還是 0.5(alpha)。也就是可能到能流行之前可能會有大改動。

 

, , , Hide

Aug/07

2

Ring Benchmark

看到這篇 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 的測試。

在嘗試簡化和優化的過程中,發現了幾件有趣的事。

  1. 把 Thread 的 priority 設得越低,結果越快;MIN_PRIORITY 比 default 快一倍。
  2. 如果更改 start() 的位置和方式,有可能會嚴重影嚴執行效率(就算它不在 ring 當中),而其影響力十分大,足以令結果相差兩倍甚至百倍。例如:
    1. 把 for loop start 改為 start 的 recursive 方式
    2. 先 Constructor 中執行 start()
  3. ThreadGroup 好像好似解決 (2.1) 所引起的問題(未確定)
  4. 根據 javaspecialists,直接 extends Thead 會比 Runnable 快一點點,但我試不出來。

, , Hide

Theme Design by devolux.org