【发布时间】:2021-08-04 12:18:40
【问题描述】:
我的朋友只想将产品差异上传到他的网上商店。所以我的想法是比较 XML 文件并仅提取更改。因此我创建了这个:
部分 XML 文件(请注意,此 XML 有更多元素,但我已将它们排除在外):
<?xml version="1.0" encoding="UTF-8"?>
<artikli>
<artikal>
<id>1039282</id>
<sifra>42640</sifra>
<naziv><![CDATA[Bluetooth zvucnik za tablet IYIGLE X7 crni]]></naziv>
</artikal>
<artikal>
<id>1048331</id>
<sifra>48888</sifra>
<naziv><![CDATA[Bluetooth zvucnik REMAX RB-M15 crni]]></naziv>
</artikal>
</artikli>
C# 脚本
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "artikal")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
else
{
reader.Read();
}
}
}
}
void ProcessFiles()
{
try
{
IEnumerable<XElement> posle = from el in StreamRootChildDoc(@"lisic2.xml")
select el;
IEnumerable<XElement> pre = from el in StreamRootChildDoc(@"lisic1.xml")
select el;
XmlDocument doc = new XmlDocument();
//(1) the xml declaration is recommended, but not mandatory
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
//(2) string.Empty makes cleaner code
XmlElement element1 = doc.CreateElement(string.Empty, "artikli", string.Empty);
doc.AppendChild(element1);
int count_files = 0;
foreach (XElement node_posle in posle)
{
count_files++;
var node_pre = pre.First(child => child.Element("id").Value == node_posle.Element("id").Value);
if (node_pre != null)
{
string pre_Value = node_pre.Value.Replace("\t", ""); ;
string posle_Value = node_posle.Value.Replace("\t", ""); ;
if (pre_Value != posle_Value)
{
var reader = node_posle.CreateReader();
reader.MoveToContent();
XmlElement element2 = doc.CreateElement(string.Empty, "artikal", reader.ReadInnerXml());
element1.AppendChild(element2);
}
}
}
doc.Save("document.xml");
}
finally
{
}
}
这可行,但在 10000 条通过记录之后,速度为每秒 18 条记录,在 14000 - 12 条记录/秒之后。有没有其他方法可以加快速度?
更新
现在,我将尝试更快地移动到已检查 XML 的相应 ID。
【问题讨论】:
-
"可以改进吗?" -- 你打开一个分析器,看看为什么它很慢。我们无法为您猜测
-
我建议使用像 BenchMarkDotNet 这样的分析器来分析你的代码。使用分析中的信息来确定最大改进的领域。但是,根据个人经验,通过查看您的代码,对性能的追求将以可读性为代价,因为您的许多 LINQ 操作都需要扩展。
-
为了像这样在原地分析预先存在的代码,我会选择内置的 VS 分析器(在 CPU 模式下)或 PerfMon。 BenchmarkDotNet 不会告诉您为什么您的代码很慢,但可以很好地比较两个备选方案
-
为什么不直接使用超越比较? XmlReader 又旧又慢。您可以在一个指令中对 xml linq 执行相同操作:XDocument = doc = XDocument.Load(uri); List
artikals = doc.Descendants("artikal").ToList(); -
XmlReader不是“又老又慢”——它是一个低级的流式 XML 解析器,而像XDocument这样的高级框架就是 built on top of!