我將小的(2-10 KB)XML文檔作爲輸入傳遞給WCF服務。現在我兩個可選的從輸入的XML中讀取數據值XPath vs DeSerialization:讀取操作的性能更好
- 反序列化到一個強類型的對象和使用對象屬性來訪問值
- 使用XPath訪問值
哪種方式速度更快?一些統計數據支持你的答案會很好。
我將小的(2-10 KB)XML文檔作爲輸入傳遞給WCF服務。現在我兩個可選的從輸入的XML中讀取數據值XPath vs DeSerialization:讀取操作的性能更好
哪種方式速度更快?一些統計數據支持你的答案會很好。
我會反序列化它。
如果您使用xpath,您將反序列化(或「加載」)到XmlDocument或其他東西。所以這兩種解決方案都使用時間反序列化。完成此操作後,由於解析該字符串,解析名稱,執行函數等所花費的時間,xpath將變慢。另外,如果你使用xpath,你不會得到類型安全。您的編譯器無法爲您檢查xpath語法。
如果您使用XmlSerializer和類,您將獲得靜態類型。真正快速訪問你的數據,如果你想用xpath查詢它們,仍然有辦法做到這一點。
此外,我想說,你的代碼可能會更容易理解與類。
唯一的缺點是xml必須始終符合相同的模式,但在您的情況下這可能不是真正的問題。
我希望你原諒沒有統計數據,我認爲這些論點足夠強大,沒有例子。如果您想要最終答案,請嘗試兩種方法並準備好秒錶。
還有第三種方法是堅持使用XML,但可以使用任何您正在使用的XML API進行查詢 - 例如LINQ to XML使得查詢在代碼中相對簡單。
您是否已經將文本解析爲XML文檔?
您是否確信這實際上是您的代碼中的一個重大性能瓶頸? (例如,如果您正在與數據庫進行交談,那麼不必擔心此問題 - 首先讓它以最簡單的方式工作)
查詢是否總是相同,或者它們是動態的某種方式?
你有一個真實的消息和查詢測試設備嗎?如果不是,您需要一個以評估您的數據給出的任何答案。如果你這樣做,我希望它可以很容易地嘗試它:)
這裏有4個的情況下,任何時候都蜱和配售:
樣本對象被讀取1000次。
你應該在意嗎?對於大多數情況,請使用內置到.net中的默認序列化程序。沒有必要偏離,這將產生最少量的代碼。這些應該是綽綽有餘,提供類型安全,並釋放自己與你的時間做更有意義的事情。在某些情況下,如果您希望從大型XML結構中挑選某些數據元素,XElement可能會很有用,但即使如此,也應該將這些元素放入強類型的DTO中。但請記住,所有方法都非常快。我已經親自在幾毫秒內序列化了一個非常廣泛和深入的對象模型(超過400個分組)。對於較小和不重要的對象,這將是子響應時間。 XMLSerializer的預熱速度比其他的慢,但可以通過SGEN進行緩解或在啓動時進行一些初始化。
詳細信息和代碼...
Xml序列
[Serializable]
public class FoobarXml
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsContent { get; set; }
[XmlElement(DataType = "date")]
public DateTime BirthDay { get; set; }
}
第一次:2448965
1000閱讀平均分:245
IXmlSerializable的
public class FoobarIXml : IXmlSerializable
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsContent { get; set; }
public DateTime BirthDay { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
var isEmptyElement = reader.IsEmptyElement;
reader.ReadStartElement();
if (!isEmptyElement)
{
Name = reader.ReadElementString("Name");
int intResult;
var success = int.TryParse(reader.ReadElementString("Age"), out intResult);
if (success)
{
Age = intResult;
}
bool boolResult;
success = bool.TryParse(reader.ReadElementString("IsContent"), out boolResult);
if (success)
{
IsContent = boolResult;
}
DateTime dateTimeResult;
success = DateTime.TryParseExact(reader.ReadElementString("BirthDay"), "yyyy-MM-dd", null,
DateTimeStyles.None, out dateTimeResult);
if (success)
{
BirthDay = dateTimeResult;
}
reader.ReadEndElement(); //Must Do
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteElementString("Name", Name);
writer.WriteElementString("Age", Age.ToString());
writer.WriteElementString("IsContent", IsContent.ToString());
writer.WriteElementString("BirthDay", BirthDay.ToString("yyyy-MM-dd"));
}
}
}
第一次:2051813
1000閱讀平均分:208
手卷
public class FoobarHandRolled
{
public FoobarHandRolled(string name, int age, bool isContent, DateTime birthDay)
{
Name = name;
Age = age;
IsContent = isContent;
BirthDay = birthDay;
}
public FoobarHandRolled(string xml)
{
if (string.IsNullOrWhiteSpace(xml))
{
return;
}
SetName(xml);
SetAge(xml);
SetIsContent(xml);
SetBirthday(xml);
}
public string Name { get; set; }
public int Age { get; set; }
public bool IsContent { get; set; }
public DateTime BirthDay { get; set; }
/// <summary>
/// Takes this object and creates an XML representation.
/// </summary>
/// <returns>An XML string that represents this object.</returns>
public override string ToString()
{
var builder = new StringBuilder();
builder.Append("<FoobarHandRolled>");
if (!string.IsNullOrWhiteSpace(Name))
{
builder.Append("<Name>" + Name + "</Name>");
}
builder.Append("<Age>" + Age + "</Age>");
builder.Append("<IsContent>" + IsContent + "</IsContent>");
builder.Append("<BirthDay>" + BirthDay.ToString("yyyy-MM-dd") + "</BirthDay>");
builder.Append("</FoobarHandRolled>");
return builder.ToString();
}
private void SetName(string xml)
{
Name = GetSubString(xml, "<Name>", "</Name>");
}
private void SetAge(string xml)
{
var ageString = GetSubString(xml, "<Age>", "</Age>");
int result;
var success = int.TryParse(ageString, out result);
if (success)
{
Age = result;
}
}
private void SetIsContent(string xml)
{
var isContentString = GetSubString(xml, "<IsContent>", "</IsContent>");
bool result;
var success = bool.TryParse(isContentString, out result);
if (success)
{
IsContent = result;
}
}
private void SetBirthday(string xml)
{
var dateString = GetSubString(xml, "<BirthDay>", "</BirthDay>");
DateTime result;
var success = DateTime.TryParseExact(dateString, "yyyy-MM-dd", null, DateTimeStyles.None, out result);
if (success)
{
BirthDay = result;
}
}
private string GetSubString(string xml, string startTag, string endTag)
{
var startIndex = xml.IndexOf(startTag, StringComparison.Ordinal);
if (startIndex < 0)
{
return null;
}
startIndex = startIndex + startTag.Length;
var endIndex = xml.IndexOf(endTag, StringComparison.Ordinal);
if (endIndex < 0)
{
return null;
}
return xml.Substring(startIndex, endIndex - startIndex);
}
}
第一次:161105
1000閱讀平均分:29
的XElement
var xDoc = XElement.Parse(xml);
var nameElement = xDoc.Element("Name");
var ageElement = xDoc.Element("Age");
var isContentElement = xDoc.Element("IsContent");
var birthDayElement = xDoc.Element("BirthDay");
string name = null;
if (nameElement != null)
{
name = nameElement.Value;
}
var age = 0;
if (ageElement != null)
{
age = int.Parse(ageElement.Value);
}
var isContent = false;
if (isContentElement != null)
{
isContent = bool.Parse(isContentElement.Value);
}
var birthDay = new DateTime();
if (birthDayElement != null)
{
birthDay = DateTime.ParseExact(birthDayElement.Value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
}
第一次:247024
1000閱讀平均分:113個
感謝喬恩, >您是否已分析的文本轉換爲XML文檔? 是的,我收到一個XMLDocument作爲輸入 >查詢是否總是相同,還是以某種方式動態? 查詢總是一樣的。 我沒有實際的數據來測試,現在一個大概的想法就足夠了 – 2008-11-10 12:51:37
我建議你現在以最簡單的方式編寫它(可能是XPath),並測量查詢所花費的時間與整個請求的性能。如果這個比例變得顯着,重新審視這個問題。 – 2008-11-10 12:55:56