1. 程式人生 > >紅黑樹與小根堆效能對比

紅黑樹與小根堆效能對比

因為nginx與libevent採用了不同的資料結構來維護超時事件,其中nginx採用了紅黑樹,libevent採用的是小根堆,所以一直比較好奇,這兩種資料結構誰在這種應用場景下更合適(當做優先權佇列來用)

好吧,好奇那就試一下就好了。。。

小根堆就用前面的那篇文章中自己實現的那個程式碼,程式碼比較挫,也沒有做什麼優化,紅黑樹通過繼承java的TreeMap來實現。。。

測試案例:

向兩種結構中分別放入相同數量的隨機數,然後不斷的將他們中的最小的節點去取出來。。。。

其中紅黑樹的程式碼如下:

[java] view plaincopyprint?
  1. package Time;  
  2. import
     java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.util.Date;  
  6. import java.util.TreeMap;  
  7. publicclass RbTree<T> extends TreeMap<T, Object>{  
  8. /** 
  9.      *  
  10.      */
  11. privatestaticfinallong serialVersionUID = 1L;  
  12. private Object PER = new Object();  
  13. publicvoid add(T node) {  
  14. this.put(node, PER);  
  15.     }  
  16. public T poll() {  
  17. if (super.size() > 0) {  
  18.             T node = super.firstKey();   //獲取當前紅黑樹最左邊的key,也就是最小的key
  19. super.remove(node);  //將這個key從樹形結構中刪除
  20. return node;  
  21.         } else {  
  22. returnnull;  
  23.         }  
  24.     }  
  25. publicstaticvoid main(String args[]) 
    throws IOException {  
  26.         RbTree<Integer> rtTree = new RbTree<Integer>();  
  27. int max = 1000000;  
  28. long before = (new Date()).getTime();  
  29. for (int i = max; i > 0; i--) {  
  30.             rtTree.add(new Integer((int)(Math.random() * max)));  
  31.         }  
  32.         Integer t = rtTree.poll();  
  33. while (t != null) {  
  34. //System.out.println(t.toString());
  35.             t = rtTree.poll();  
  36.         }  
  37. long after = (new Date()).getTime();  
  38.         System.out.println(((double)after - (double)before) / 1000);  
  39.         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
  40.         reader.readLine();  
  41.     }  
  42. }  
package Time;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.TreeMap;

public class RbTree<T> extends TreeMap<T, Object>{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Object PER = new Object();
		
	
	public void add(T node) {
		this.put(node, PER);
	}
	
	public T poll() {
		if (super.size() > 0) {
			T node = super.firstKey();   //獲取當前紅黑樹最左邊的key,也就是最小的key
			super.remove(node);  //將這個key從樹形結構中刪除
			return node;
		} else {
			return null;
		}
	}
	
	
	public static void main(String args[]) throws IOException {
		RbTree<Integer> rtTree = new RbTree<Integer>();
		int max = 1000000;
		long before = (new Date()).getTime();
		for (int i = max; i > 0; i--) {
			rtTree.add(new Integer((int)(Math.random() * max)));
		}
	
		Integer t = rtTree.poll();
		while (t != null) {
			//System.out.println(t.toString());
			t = rtTree.poll();
		}
		
		long after = (new Date()).getTime();
		System.out.println(((double)after - (double)before) / 1000);
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		reader.readLine();
	}
	
}

其中,分別測試了100萬,200萬,600萬和1000萬的資料量。。。

最後的結論是:

紅黑樹的效能比小根堆好(都是近似時間複雜度O(nlogn)  ),一般處理相同的資料量,小根堆需要的時間大概是紅黑樹的兩倍左右,當然這也不排除我寫的小根堆程式碼不行,畢竟紅黑樹用的程式碼基本上都是java類庫的。。。。。。