PDA

View Full Version : سورت کردن آرایه ی xmlnode با attribute های آن



میلاد قاضی پور
شنبه 30 مهر 1390, 13:40 عصر
سلام . من یک آرایه از xmlnode دارم . میخوام این آرایه رو بر اساس اتریبیوت های نودهای وارده سورت کنم . سریعترین راه حل ممکن چی هست؟

mehdi.mousavi
شنبه 30 مهر 1390, 14:57 عصر
سلام.
اگر فرض کنیم XML مورد نظر این باشه:

string xml = @" <xml>
<nodes>
<node myattr='32'/>
<node myattr='10'/>
<node myattr='12'/>
<node myattr='6'/>
</nodes>
</xml>";


و بتونیم از LINQ استفاده کنیم، میشه بدین شکل عمل کرد:

XDocument doc = XDocument.Parse(xml);
foreach (XElement node in doc.XPathSelectElements("//nodes/node").OrderBy(n => int.Parse(n.Attribute("myattr").Value)))
{
string nodeValue = node.Value;
//Whatever ...
}


اگر نتونیم از LINQ استفاده کنیم، می تونیم از XPathNavigator استفاده کنیم:


XDocument doc = XDocument.Parse(xml);

XPathNavigator nav = doc.CreateNavigator();
XPathExpression expr = nav.Compile("//nodes/node");

expr.AddSort("@myattr", XmlSortOrder.Ascending, XmlCaseOrder.None, string.Empty, XmlDataType.Number);

XPathNodeIterator iterator = nav.Select(expr);
while (iterator.MoveNext())
{
XPathNavigator element = iterator.Current.Clone();
if (element.MoveToFirstAttribute())
{
int myattr = element.ValueAsInt;
//Whatever...
}
}


موفق باشید.

میلاد قاضی پور
یک شنبه 01 آبان 1390, 06:08 صبح
البته با الگوریتمهای قرون وسطا مثل این هم میشد اما میخواستم بدونم کدوم سربار کمتری ایجاد میکنه؟


XmlNode[] nodesOfWeekArr = nodesOfWeek.ToArray();
XmlNode tempNode;
for (int i = 0; i < nodesOfWeekArr.Length-1; i++)
{
for (int j = i+1; j < nodesOfWeekArr.Length; j++)
{
if (int.Parse(nodesOfWeekArr[i].Attributes["Visit"].Value)
< int.Parse(nodesOfWeekArr[j].Attributes["Visit"].Value))
{
tempNode = nodesOfWeekArr[i];
nodesOfWeekArr[i] = nodesOfWeekArr[j];
nodesOfWeekArr[j] = tempNode;
}
}
}

mehdi.mousavi
یک شنبه 08 آبان 1390, 00:54 صبح
سلام.
من کدهایی که ارسال کرده بودم رو قدری بررسی کردم. برای اینکار، یک XML با همون ساختار بالایی متشکل از 5 میلیون node با myattr های random از int.MinValue تا int.MaxValue ایجاد کردم و از این XML برای بررسی Performance دو کد فوق استفاده کردم.

کد اول، یعنی:


foreach (XElement node in doc.XPathSelectElements("//nodes/node").OrderBy(n => int.Parse(n.Attribute("myattr").Value)))
{
int value = Convert.ToInt32(node.Attribute("myattr").Value);
//Whatever ...
}


11.04 ثانیه زمان برد تا Element ها رو مرتب کنه و حلقه فوق اجرا بشه. کد دوم، یعنی کدی که از XPathNavigator در اون استفاده کردم، 110 ثانیه زمان برد!!! یعنی بیش از 10 برابر قبلی. بنابراین پر واضحه که بین این دو، استفاده از LINQ ارجحیت داره. اما، چون من از CPU های Multi-Core استفاده می کنم، کد فوق رو به کد زیر تغییر دادم (جای LINQ از PLINQ استفاده کردم) و مجددا زمان sort و iterate کردن element ها رو بررسی کردم:


foreach (XElement node in doc.XPathSelectElements("//nodes/node").AsParallel().OrderBy(n => int.Parse(n.Attribute("myattr").Value)))
{
int value = Convert.ToInt32(node.Attribute("myattr").Value);
//Whatever ...
}

با این تغییر به ظاهر کوچک، سرعت مرتب سازی به 6.8 ثانیه کاهش پیدا کرد...

موفق باشید.