一直很忙,壓了很多貼,今天發一篇吧。後面的看心情吧。
今天群裡有人問如何解析web.config方便,然後我就推薦了Linq to XML,然後就有人說“我寧可XmlDocument,再SeleteNodes和SeleteNode”,不要用LINQ之類的,甚至否定EntityFramework等一系列框架,認為這些都是所謂的“懶人技術”,都是以犧牲性能為代價的。我在這裡想申明一點,沒有測試就沒有發言權,並不是所有的”懶人技術“都是以犧牲性能為代價的。我這人比較喜歡就技術論技術,不喜歡武斷的言論,於是展開了討論。本文只是做一個總結。
很多同學已經做過性能測試了,我就不重復了,如下鏈接:
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有一位優秀的母親——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 方法時,都必須在內部執行以下操作:
與相應的 LINQ to XML 查詢完成的工作相比,這需要執行非常多的工作。
除此之外,LINQ to XML還繼承了父親的延遲執行的優良傳統,也能夠提高性能。
父親這麼優秀,XmlDocument自然無法相比了。
所以,富二代和官二代起點就比你高,你如果不比他們多付出N倍的努力,你甚至連他們的起點都無法到達。
科普下延遲執行的知識:
延遲執行意味著表達式的計算延遲,直到真正需要它的實現值為止。 當必須操作大型數據集合,特別是在包含一系列鏈接的查詢或操作的程序中操作時,延遲執行可以大大改善性能。 在最佳情況下,延遲執行只允許對源集合的單個循環訪問。
LINQ 技術廣泛應用了延遲執行,包括在核心 System.Linq 類的成員和不同 LINQ 命名空間中的擴展方法(如 System.Xml.Linq.Extensions)中使用。
除了上面的,其他的還有些他在成長過程中,自己提升的優點,比如:XName 和 XNamespace 對象是原子化的,如果這兩個對象包含相同的名字,則它們會引用同一個對象。 也就是說當比較兩個原子化名稱是否相等時,只需確定這兩個引用是否指向同一個對象,而不必進行很”耗費時間“的字符串比較,這個是有助於性能提升的。
雖然這不是拍電影,但是尾聲還是必須的。
var result = e.Elements("ds")
.Where(ds => ds.Element("ClassID").Value == "64")//取選擇的元素《1》。
.Select(ds => ds.Element("arrChildID").Value.Split(','))//預先准備ID數組《2》。
.Select(arrid => e.Elements("ds")
.Where(ds2 => arrid.Contains(ds2.Element("ClassID").Value)))//由於《1》其實只有一條結果,所以此子過程之執行一次。
.SelectMany(ds2 => ds2);//合並結果集合
//已測
var par = from settings in XElement.Load("monitorSettings.xml").Elements("rootpath") select settings;
沒讀出來數據吧