為什么LINQ to XML的性能要優於XmlDocument?


一直很忙,壓了很多貼,今天發一篇吧。后面的看心情吧。

今天群里有人問如何解析web.config方便,然后我就推薦了Linq to XML,然后就有人說“我寧可XmlDocument,再SeleteNodes和SeleteNode”,不要用LINQ之類的,甚至否定EntityFramework等一系列框架,認為這些都是所謂的“懶人技術”,都是以犧牲性能為代價的。我在這里想申明一點,沒有測試就沒有發言權,並不是所有的”懶人技術“都是以犧牲性能為代價的。我這人比較喜歡就技術論技術,不喜歡武斷的言論,於是展開了討論。本文只是做一個總結。

 

LINQ to XML的性能測試

很多同學已經做過性能測試了,我就不重復了,如下鏈接:

XML數據讀取方式性能比較(一)

XML數據讀取方式性能比較(二)

從上面的結果我們不能看出,Linq to Xml的性能明顯是優於XmlDocument的。我這人比較喜歡追根溯源,如果單從這個,總是有人會產生各種悖論,比如:


【碼帥】-------- 13:52:01
確定真是LINQ高嗎
【碼奴】-------- 13:52:32
什么高?
【碼帥】-------- 13:52:42
為什么上面2個都有Add
【碼帥】-------- 13:52:49
下面2個都沒有
【碼帥】-------- 13:52:54
這測試公正嗎
【碼帥】-------- 13:53:18
好比一個是直接new Object[]
【碼帥】-------- 13:54:38
4個測試就有問題
【碼帥】-------- 13:56:03
2個40多秒的都有這Add

其實他的問題都沒到點上,這里根本就不是Add的問題,Linq的ToList()方法肯定也干了這事,如果懷疑這里,完全可以自己去寫個測試。所以我覺得有必要說下為什么LINQ to XML性能優於XmlDocument的緣由了。

為什么LINQ to XML性能優於XmlDocument?

首先,我們需要明白的一點是:

LINQ to XML有一位優秀的母親——XmlReader。

LINQ to XML 在 XmlReader 基礎之上實現的,也就是LINQ to XML源於XmlReader,高於XmlReader。

遺傳基因很重要!

XmlReader 是一種快速的只進非緩存分析器。他丫的對XML 數據流的訪問是只讀的。

 

其次,LINQ to XML有一位出色的父親——Linq。

LINQ to XML 的一個最重要的性能優勢(與 XmlDocument 相比)為:LINQ to XML 中的查詢是靜態編譯的,而 XPath 查詢則必須在運行時進行解釋。

這個因素是性能中至關重要的,所謂”子不教,父之過“!

也就是說,LINQ to XML的查詢被編譯成靜態鏈接的方法調用,這樣的性能提升是巨大的。反觀XmlDocument,它在每次調用 SelectNodes 方法時,都必須在內部執行以下操作:

  1. 分析包含 XPath 表達式的字符串,並將字符串划分成多個標記。
  2. 驗證這些標記以確保 XPath 表達式有效。
  3. 將表達式轉換為內部表達式樹。
  4. 循環訪問節點,為基於表達式計算的結果集選擇適當的節點。

與相應的 LINQ to XML 查詢完成的工作相比,這需要執行非常多的工作。

除此之外,LINQ to XML還繼承了父親的延遲執行的優良傳統,也能夠提高性能。

父親這么優秀,XmlDocument自然無法相比了。

所以,富二代和官二代起點就比你高,你如果不比他們多付出N倍的努力,你甚至連他們的起點都無法到達。

 

科普下延遲執行的知識:

延遲執行意味着表達式的計算延遲,直到真正需要它的實現值為止。 當必須操作大型數據集合,特別是在包含一系列鏈接的查詢或操作的程序中操作時,延遲執行可以大大改善性能。 在最佳情況下,延遲執行只允許對源集合的單個循環訪問。
LINQ 技術廣泛應用了延遲執行,包括在核心 System.Linq 類的成員和不同 LINQ 命名空間中的擴展方法(如 System.Xml.Linq.Extensions)中使用。

 

除了上面的,其他的還有些他在成長過程中,自己提升的優點,比如:XName 和 XNamespace 對象是原子化的,如果這兩個對象包含相同的名字,則它們會引用同一個對象。 也就是說當比較兩個原子化名稱是否相等時,只需確定這兩個引用是否指向同一個對象,而不必進行很”耗費時間“的字符串比較,這個是有助於性能提升的。

 

尾聲

雖然這不是拍電影,但是尾聲還是必須的。

  1. 沒有測試就沒有發言權,並不是所有的”懶人技術“都是以犧牲性能為代價的
  2. 雖然Linq to SQL的名聲不大好,但是LINQ to XML卻應該是實至名歸。而且Linq to SQL的兒子EF正在挽回她的名聲,如果你沒用過,請不要說他不行,如果你用的不當,請也別說他不行。
  3. 懶人技術都是懶人發明的,但是往往就是這些懶人推動了技術的前進。
  4. 每一種技術和框架都是有使用場景的,如果你用錯了場景,請不要說他不行。
  5. 合理把控性能,在大多數非苛刻場景,不到1毫秒甚至更多的差別,你完全不必要浪費1小時以上的精力,認真提高開發效率才是關鍵的。比如枚舉類型的ToString()。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM