Reputation: 21
I'm trying to build objects based on xmlreader:
List<Element> units = new List<Element>();
string path = "D:\\Item\\Unit.xml";
XElement xelement = XElement.Load(path);
IEnumerable<XElement> elements = xelement.Elements();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
//and next 30 options included try / catch for int.Parse
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row id="1">
<Name>Freighter</Name>
<Picture>Item\Freighter.gif</Picture>
... and 30 next rows with data for each "unit"
</row>
... and 30 next units...
<rows>
As I told, XML is 23kB file with 30 rows per each unit, with total 30 units in file. Not sure why this code is so slow: it took 670 miliseconds (i3 processor). The slowest part is obiect fillig, but not sure how to improve it.
The complete code looks exactly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Diagnostics;
namespace element_reader
{
class Program
{
static void Main(string[] args)
{
CustomStopwatch sw = new CustomStopwatch();
sw.Start();
List<Element> ships = new List<Element>();
string path = "D:\\Ship_test.xml";
XElement xelement = XElement.Load(path);
IEnumerable<XElement> elements = xelement.Elements();
sw.Stop();
Console.WriteLine("Stopwatch elapsed: {0}, StartAt: {1}, EndAt: {2}", sw.ElapsedMilliseconds, sw.StartAt.Value, sw.EndAt.Value);
sw.Start();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
try
{
stb.Prt = int.Parse(c.Element("PRT").Value);
}
catch
{ stb.Prt = 0; }
try
{
stb.Lrt = int.Parse(c.Element("LRT").Value);
}
catch
{ stb.Lrt = 0; }
stb.Special = c.Element("Special").Value;
try
{
stb.Wep = int.Parse(c.Element("Wep").Value);
}
catch
{ stb.Wep = 0; }
try
{
stb.Con = int.Parse(c.Element("Con").Value);
}
catch
{ stb.Con = 0; }
try
{
stb.Ene = int.Parse(c.Element("Ene").Value);
}
catch
{ stb.Ene = 0; }
try
{
stb.Ele = int.Parse(c.Element("Ele").Value);
}
catch
{ stb.Ele = 0; }
try
{
stb.Prp = int.Parse(c.Element("Prp").Value);
}
catch
{ stb.Prp = 0; }
try
{
stb.Bio = int.Parse(c.Element("Bio").Value);
}
catch
{ stb.Bio = 0; }
try
{
stb.Mass = int.Parse(c.Element("Mass").Value);
}
catch
{ stb.Mass = 0; }
try
{
stb.Iro = int.Parse(c.Element("Iro").Value);
}
catch
{ stb.Iro = 0; }
try
{
stb.Bor = int.Parse(c.Element("Bor").Value);
}
catch
{ stb.Bor = 0; }
try
{
stb.Ger = int.Parse(c.Element("Ger").Value);
}
catch
{ stb.Ger = 0; }
try
{
stb.Res = int.Parse(c.Element("Res").Value);
}
catch
{ stb.Res = 0; }
ships.Add(stb);
}
sw.Stop();
Console.WriteLine("Stopwatch elapsed: {0}, StartAt: {1}, EndAt: {2}", sw.ElapsedMilliseconds, sw.StartAt.Value, sw.EndAt.Value);
Console.Read();
}
}
public class Element
{
public string Name;
public string Picture;
public int Prt;
public int Lrt;
public string Special;
public int Con;
public int Wep;
public int Ene;
public int Ele;
public int Prp;
public int Bio;
public int Mass;
public int Iro;
public int Bor;
public int Ger;
public int Res;
}
public class CustomStopwatch : Stopwatch
{
public DateTime? StartAt { get; private set; }
public DateTime? EndAt { get; private set; }
public void Start()
{
StartAt = DateTime.Now;
base.Start();
}
public void Stop()
{
EndAt = DateTime.Now;
base.Stop();
}
}
}
When the part of XML looks exactly:
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row id="1">
<Name>Small Freighter</Name>
<Picture>Item\Ship\Ship01_1.gif</Picture>
<Description></Description>
<PRT></PRT>
<LRT></LRT>
<Special></Special>
<Ene>0</Ene>
<Wep>0</Wep>
<Prp>0</Prp>
<Con>0</Con>
<Ele>0</Ele>
<Bio>0</Bio>
<Slot1>-150, 0, Engine, 1, 1, 1</Slot1>
<Slot2>-50, 0, Cargo, 70, 1, 1</Slot2>
<Slot3>50, 0, DEF, 1, 1, 1</Slot3>
<Slot4>150, 0, SEM, 1, 1, 1</Slot4>
<Mass>25</Mass>
<Res>20</Res>
<Iro>12</Iro>
<Res>0</Res>
<Ger>17</Ger>
<Fuel>130</Fuel>
<Cargo>70</Cargo>
<HPD_arm>25</HPD_arm>
<Initiative>0</Initiative>
</row>
</rows>
Result is 70ms for 1kB file !!! If I have 20 files to load with 20-30 rows each this method is completely useless. Please notice that I do not use all data located in file.
Upvotes: 0
Views: 157
Reputation: 5884
You didn't provide full xml
file content, so I just only can suggest you one thing.
Use int.TryParse
instead of int.Parse
. I bet your code throws hundreds of exceptions which are very CPU expensive.
Upvotes: 1
Reputation: 34421
Usually the code should look like this :
List<Element> elements = xelement.Descendants("TagName").Select(x => new Element() {
Name = (string)x.Element("Name"),
Picture = (string)x.Element("Picture")
}).ToList();
Here is the comparison of the times Time 1 = '11.0082', Time 2 = '4.0032'
Here is code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
Element newElement = new Element() {
Name = "John",
Picture = "Dorian Grey",
Data1 = "1",
Data2 = "1",
Data3 = "1",
Data4 = "1",
Data5 = "1",
Data6 = "1",
Data7 = "1",
Data8 = "1",
Data9 = "1",
Data10 = "1",
Data11 = "1",
Data12 = "1",
Data13 = "1",
Data14 = "1",
Data15 = "1",
Data16 = "1",
Data17 = "1",
Data18 = "1",
Data19 = "1",
Data20 = "1",
Data21 = "1",
Data22 = "1",
Data23 = "1",
Data24 = "1",
Data25 = "1",
Data26 = "1",
Data27 = "1",
Data28 = "1",
Data29 = "1",
Data30 = "1"
};
Root root = new Root();
for (int i = 0; i < 29; i++)
{
root.elements.Add(newElement);
}
XmlWriterSettings setting = new XmlWriterSettings();
setting.Indent = true;
XmlWriter writer = XmlWriter.Create(FILENAME, setting);
XmlSerializer serializer = new XmlSerializer(typeof(Root));
serializer.Serialize(writer, root);
writer.Flush();
writer.Close();
XDocument doc = XDocument.Load(FILENAME);
DateTime start1 = DateTime.Now;
List<Element> units = new List<Element>();
List<XElement> elements = doc.Root.Elements().ToList();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
stb.Data1 = c.Element("Data1").Value;
stb.Data2 = c.Element("Data2").Value;
stb.Data3 = c.Element("Data3").Value;
stb.Data4 = c.Element("Data4").Value;
stb.Data5 = c.Element("Data5").Value;
stb.Data6 = c.Element("Data6").Value;
stb.Data7 = c.Element("Data7").Value;
stb.Data8 = c.Element("Data8").Value;
stb.Data9 = c.Element("Data9").Value;
stb.Data10 = c.Element("Data10").Value;
stb.Data11 = c.Element("Data11").Value;
stb.Data12 = c.Element("Data12").Value;
stb.Data13 = c.Element("Data13").Value;
stb.Data14 = c.Element("Data14").Value;
stb.Data15 = c.Element("Data15").Value;
stb.Data16 = c.Element("Data16").Value;
stb.Data17 = c.Element("Data17").Value;
stb.Data18 = c.Element("Data18").Value;
stb.Data19 = c.Element("Data19").Value;
stb.Data20 = c.Element("Data20").Value;
stb.Data21 = c.Element("Data21").Value;
stb.Data22 = c.Element("Data22").Value;
stb.Data23 = c.Element("Data23").Value;
stb.Data24 = c.Element("Data24").Value;
stb.Data25 = c.Element("Data25").Value;
stb.Data26 = c.Element("Data26").Value;
stb.Data27 = c.Element("Data27").Value;
stb.Data28 = c.Element("Data28").Value;
stb.Data29 = c.Element("Data29").Value;
stb.Data30 = c.Element("Data30").Value;
units.Add(stb);
}
DateTime end1 = DateTime.Now;
DateTime start2 = DateTime.Now;
List<Element> elements2 = doc.Descendants("elements").Select(x => new Element()
{
Name = (string)x.Element("Name"),
Picture = (string)x.Element("Picture"),
Data1 = (string)x.Element("Data1"),
Data2 = (string)x.Element("Data2"),
Data3 = (string)x.Element("Data3"),
Data4 = (string)x.Element("Data4"),
Data5 = (string)x.Element("Data5"),
Data6 = (string)x.Element("Data6"),
Data7 = (string)x.Element("Data7"),
Data8 = (string)x.Element("Data8"),
Data9 = (string)x.Element("Data9"),
Data10 = (string)x.Element("Data10"),
Data11 = (string)x.Element("Data11"),
Data12 = (string)x.Element("Data12"),
Data13 = (string)x.Element("Data13"),
Data14 = (string)x.Element("Data14"),
Data15 = (string)x.Element("Data15"),
Data16 = (string)x.Element("Data16"),
Data17 = (string)x.Element("Data17"),
Data18 = (string)x.Element("Data18"),
Data19 = (string)x.Element("Data19"),
Data20 = (string)x.Element("Data20"),
Data21 = (string)x.Element("Data21"),
Data22 = (string)x.Element("Data22"),
Data23 = (string)x.Element("Data23"),
Data24 = (string)x.Element("Data24"),
Data25 = (string)x.Element("Data25"),
Data26 = (string)x.Element("Data26"),
Data27 = (string)x.Element("Data27"),
Data28 = (string)x.Element("Data28"),
Data29 = (string)x.Element("Data29"),
Data30 = (string)x.Element("Data30"),
}).ToList();
DateTime end2 = DateTime.Now;
string results = string.Format("Time 1 = '{0}', Time 2 = '{1}'", (end1 - start1).TotalMilliseconds, (end2 - start2).TotalMilliseconds);
Console.ReadLine();
}
}
public class Root
{
[XmlElement]
public List<Element> elements = new List<Element>();
}
public class Element
{
public string Name { get; set; }
public string Picture { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
public string Data4 { get; set; }
public string Data5 { get; set; }
public string Data6 { get; set; }
public string Data7 { get; set; }
public string Data8 { get; set; }
public string Data9 { get; set; }
public string Data10 { get; set; }
public string Data11 { get; set; }
public string Data12 { get; set; }
public string Data13 { get; set; }
public string Data14 { get; set; }
public string Data15 { get; set; }
public string Data16 { get; set; }
public string Data17 { get; set; }
public string Data18 { get; set; }
public string Data19 { get; set; }
public string Data20 { get; set; }
public string Data21 { get; set; }
public string Data22 { get; set; }
public string Data23 { get; set; }
public string Data24 { get; set; }
public string Data25 { get; set; }
public string Data26 { get; set; }
public string Data27 { get; set; }
public string Data28 { get; set; }
public string Data29 { get; set; }
public string Data30 { get; set; }
}
}
Upvotes: 0