標籤:

效率比擬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也就是類似於&apos;這類的東西)

當然有些地方以後可能會做調整比如說那個超級長的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)的忽視?

TAG:C | XML | 软件工程 |