程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 超大實時排行榜的解決方案,排行榜解決方案

超大實時排行榜的解決方案,排行榜解決方案

編輯:C++入門知識

超大實時排行榜的解決方案,排行榜解決方案


標題是個噱頭,這裡只說積分數據全部裝載到內存

 

首先,玩家的積分什麼的有單獨的表存儲,這裡不談序列化,語言是C++

假定score是double,id是int64

然後計算空間需求,這裡假設實現了專用無稅收的內存適配器
32位進程大地址,每個節點32字節,4G的進程可以放下1.34億的數據,去掉進程本身的邊角,1.2億
64位進程,每個節點48字節,1億數據需要4.47G內存,根據需要自己給服務器加內存吧...

然後就沒有然後了...

就是這麼簡單粗暴的把所有積分塞進內存

查詢第k名玩家的id
查詢積分n可以排多少名

好吧,存在的問題是,更新略惡心,用積分做k,存在相同積分時候,equal_range後遍歷找到對應id,erase後重新insert吧

序列化什麼的,可以考慮內存映射文件+對應內存適配器來搞定 

 

 

然後說說容器本身!

 

自己碼的sorted_set類,可隨機訪問的kv容器,std::multimap風格,允許重復key

operator[]操作不明確下標訪問或是key-value查詢,所以沒有實現

內部二叉樹結構,除了parent,left,right之外,只有一個SBT需要的size域,4個指針大小

隨機訪問迭代器,可以+/-/+=/-=操作,可以兩個迭代器相減求距離

這裡的rank從0開始,並沒有給出select函數,而是參考std::vector使用at隨機訪問

各種接口的復雜度不超過O(log2n),參考陳啟峰的size balanced tree

實測4千萬數據,可以達到每秒百萬查,作為一般的游戲行業,算是足夠了

樹結構還算平衡,順序/亂序插入的時間開銷是std::multimap的1.2倍左右,這裡請教是不是我實現有問題?

 

 

 

最後念叨點題外的!

 

說起來個人比較懶...

最初是我的俄羅斯方塊AI裡面的需求,對有序的std::vector不斷歸並,std::merge成了性能瓶頸!

之後考慮節AI內部本身就是一個個節點,直接建立二叉樹來排序效果應該不錯,但是AI內部節點都是百萬級別!

於是直接用std::map的問題就是new的時候會有稅收,而且本身就是AI節點,所以參考std::map源碼直接搞了個一個不去new節點,直接把外部節點掛在樹上的容器!還沒有clear開銷!

似乎就是這樣了,然而後來聽說size balanced tree比red black tree性能還好,然後改造起來也不麻煩!索性順手加上那個神maintain來測試一下性能~

結果實測,比紅黑樹稍慢,也可能是我的實現有問題?沒有達到陳啟峰說的超越紅黑樹,不過也算是一個數量級~

最終俄羅斯方塊AI還是用了紅黑樹...

------分割線------

群裡某人問:"SortedList相當於C++裡的啥容器?"

於是我就把之前的外掛節點的容器拿來重構...

暫時叫sorted_set,跟redis的Z系列很像,同npm的sorted-set(內部跳表實現)

相比其他的rank tree實現,附加域沒有任何浪費什麼的太漂亮了

 

本文3個目的

1.安利一下size balanced tree
2.找高人看看我的實現有什麼問題
3.拋磚引玉

 

最後傳送門

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved