紅黑樹與小根堆效能對比
阿新 • • 發佈:2019-01-31
因為nginx與libevent採用了不同的資料結構來維護超時事件,其中nginx採用了紅黑樹,libevent採用的是小根堆,所以一直比較好奇,這兩種資料結構誰在這種應用場景下更合適(當做優先權佇列來用)
好吧,好奇那就試一下就好了。。。
小根堆就用前面的那篇文章中自己實現的那個程式碼,程式碼比較挫,也沒有做什麼優化,紅黑樹通過繼承java的TreeMap來實現。。。
測試案例:
向兩種結構中分別放入相同數量的隨機數,然後不斷的將他們中的最小的節點去取出來。。。。
其中紅黑樹的程式碼如下:
[java] view plaincopyprint?- package Time;
- import
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.Date;
- import java.util.TreeMap;
- publicclass RbTree<T> extends TreeMap<T, Object>{
- /**
- *
- */
- privatestaticfinallong serialVersionUID = 1L;
- private Object PER = new Object();
- publicvoid 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 {
- returnnull;
- }
- }
- publicstaticvoid main(String args[])
- 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();
- }
- }
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類庫的。。。。。。