效率比擬RapidXml的XML解析庫Textcat::XML即將完工
一、寫在前面
寫了兩個月,自己造的XML解析輪子基本上達到了能用的狀態,美其名曰Textcat::XML。(Textcat命名空間裡面以後還會放其它的輪子啦XD)
二、簡介
這個輪子很大程度上參考了RapidXml和@Milo Yip 大大的RapidJSON這兩個各自在XML和JSON解析中速度數一數二的庫:
- 快速
- 易用
- 不依賴其它庫
- Header Only
- 原位解析
- 支持SAX/DOM兩種形式的解析
- ……
這裡學習了一下RapidJSON中在SAX外麵包一個DOM的做法,非常方便地實現了兩套API。當然,需要編譯器支持C++11(這好像是廢話吧)。
我也用模板來生成了一些查找表,所以代碼中也不像RapidXml那樣有一大堆打表啦~比如說想弄一個十六進位轉換的表,RapidXml裡面是這樣做的:
(求不吐槽IDE)
而Textcat::XML中有一個Table模板,然後需要打表時只需要寫這麼一個東西:
class Hexadecimal { public: static constexpr std::uint8_t test(std::uint8_t t) { return (t >= "0" && t <= "9") ? (t - "0") : ((t >= "A" && t <= "F") ? (t - "A" + 10) : ((t >= "a" && t <= "f") ? (t - "a" + 10) : 255)); } };
然後用
Table<Hexadecimal>::table[x]
就能得到一張可愛的表啦~完全省去了手工打表的痛苦,調整起來也方便,而且性能無損。當然也為以後加上SSE加速之類的提供了方便(其實寫了一個用SSE2加速的Skipper但不知道為什麼速度反而下降了ORZ……)
順帶一提,參考了這兩份標準:
Extensible Markup Language (XML) 1.0
Document Object Model (Core) Level 1(其實實現的DOM不是完全標準但也和標準很類似。)
三、舉幾個例子
SAX解析的用法:
class Handler : public Textcat::XML::HandlerBase { public: bool text(const char* value, size_t valueLength) { std::cout << value << "
"; return true; } void error(size_t pos, const char* str) { std::cout << "error: " << pos << ", " << str << "
"; } };// std::vector<char> data;Textcat::XML::Parser parser;Handler handler;bool result = parser.parse<Textcat::XML::Parser::Flags::None>(data.data(), handler);
可以輸出data存儲的XML中所有文本內容(去除了頭尾空格以及解析了Reference也就是類似於'這類的東西)
當然有些地方以後可能會做調整比如說那個超級長的Flag……
DOM解析的用法:
// std::vector<char> data;Textcat::XML::Document document;bool result = document.parse<Textcat::XML::Parser::Flags::None>(data.data());
可以解析data存儲的XML並存放在Document中。
四、關於速度
造的時候為了檢驗速度,自己寫了一個小的Benchmark,使用Textcat::XML(DOM解析)和RapidXml交替解析,文件是RapidXml的測試數據中的一份(mscorlib.xml,7211319位元組)以及一份OpenGL官網上拉下來的文件(2553969位元組)(實在找不到更大的了……自己生成數據的話怕被噴),用QueryPerformanceCounter計時,只測量解析時間(包括申請釋放內存的時間),總共測量256次取最小值。當然,我將RapidXml的解析Flag調整為了和Textcat::XML相同的以保證公平(基本上是所有功能全開)。結果看起來是這樣的:
顯示的數據是RapidXml的時間比Textcat::XML的時間,也就是Textcat::XML的速度比RapidXml略快一些。當然不同機器上的結果可能不同,不過這已經足以說明Textcat::XML的性能是比較優秀的啦。(覺得我在吹牛的話請大大們輕噴T-T)(如果知道現存的比RapidXml更快的庫的話歡迎指出)
五、某些沒做完的東西
至於現在為什麼還沒放到GitHub上是因為還有點東西沒做完啦……比如說:
- 各種編碼
- 數據流
- 更完善的錯誤處理
- Stringifier(現在只是勉強弄了一個簡陋的operator <<湊合著用)
拭目以待吧~
六、隨便再扯點
剛剛NOIP進了複賽,不能光顧著造輪子不去做題了……雖然身在弱省但能拿到一等最好了T-T好想進NOI啊啊啊啊啊(這就是你不放到GitHub上的原因?(逃
推薦閱讀:
※cocos2d-x代碼質量如何?
※寫基於圖形API(如WebGL)的引擎主要考慮的設計因素有哪些?
※如何看待武漢大學軟體工程國家重點實驗室因評估未通過遭摘牌?
※如何評價中國大學軟體課程中對於流行技術(如Git)的忽視?