В настоящее время я изучаю C#, и я работал над парсером XML за последние два дня. Это действительно работает, моя проблема - это количество времени, затрачиваемого на анализ более 10 тыс. Страниц. это мой код.C# Запуск всей темы за один раз при разборе
public static void startParse(int id_min, int id_max, int numberofthreads)
{
int start;
int end;
int part;
int threadnbrs;
threadnbrs = numberofthreads;
List<Thread> workerThreads;
List<string> results;
part = (id_max - id_min)/threadnbrs;
start = id_min;
end = 0;
workerThreads = new List<Thread>();
results = new List<string>();
for (int i = 0; i < threadnbrs; i++)
{
if (i != 0)
start = end + 1;
end = start + (part);
if (i == (threadnbrs - 1))
end = id_max;
int _i = i;
int _start = start;
int _end = end;
Thread t = new Thread(() =>
{
Console.WriteLine("i = " + _i);
Console.WriteLine("start =" + _start);
Console.WriteLine("end =" + _end + "\r\n");
string parse = new ParseWH().parse(_start, _end);
lock (results)
{
results.Add(parse);
}
});
workerThreads.Add(t);
t.Start();
}
foreach (Thread thread in workerThreads)
thread.Join();
File.WriteAllText(".\\result.txt", String.Join("", results));
Console.Beep();
}
то, что я на самом деле делать это расщепление в другом потоке ряд элементов, которые должны быть разобраны так каждый дескриптор потока элементов X.
для каждых 100 элементов занимает около 20 секунд. однако мне понадобилось 17 минут для разбора 10 0000 элементов.
что мне нужно, каждая нить работает одновременно на 100 из этих 10 000 элементов, поэтому это можно сделать за 20 секунд. есть ли для этого решение?
Анализировать Код:
public string parse(int id_min, int id_max)
{
XmlDocument xml;
WebClient user;
XmlElement element;
XmlNodeList nodes;
string result;
string address;
int i;
//Console.WriteLine(id_min);
//Console.WriteLine(id_max);
i = id_min;
result = "";
xml = new XmlDocument();
while (i <= id_max)
{
user = new WebClient();
// user.Headers.Add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
user.Encoding = UTF8Encoding.UTF8;
address = "http://fr.wowhead.com/item=" + i + "?xml";
if (address != null)
xml.LoadXml(user.DownloadString(new Uri(address)));
element = xml.DocumentElement;
nodes = element.SelectNodes("/wowhead");
if (xml.SelectSingleNode("/wowhead/error") != null)
{
Console.WriteLine("error " + i);
i++;
continue;
}
result += "INSERT INTO item_wh (entry, class, subclass, displayId, ,quality, name, level) VALUES (";
foreach (XmlNode node in nodes)
{
// entry
result += node["item"].Attributes["id"].InnerText;
result += ", ";
// class
result += node["item"]["class"].Attributes["id"].InnerText;
result += ", ";
// subclass
result += node["item"]["subclass"].Attributes["id"].InnerText;
result += ", ";
// displayId
result += node["item"]["icon"].Attributes["displayId"].InnerText;
result += ", ";
// quality
result += node["item"]["quality"].Attributes["id"].InnerText;
result += ", \"";
// name
result += node["item"]["name"].InnerText;
result += "\", ";
// level
result += node["item"]["level"].InnerText;
result += ");";
// bakcline
result += "\r\n";
}
i++;
}
return (result);
}
Таким образом, для анализа 100 элементов требуется 20 секунд ... как вы ожидаете получить пропускную способность 1000x, разобрав в 1000 раз столько элементов за такое же количество времени? Threading не просто волшебным образом дает вам свободную вычислительную мощность или пропускную способность сети (мы не знаем, что занимает время для 100 элементов). –
@JonSkeet - но добавление потоков позволит им получить доступ к нескольким процессорным ядрам, тогда как при этом линейно будет использовать только одно ядро максимум. На многоядерной машине нарезание резьбы приведет к увеличению количества ядер в процедуре. Согласитесь полностью, что проблема заключается в времени, затрачиваемом на разбор 100 предметов, которые являются чрезмерно чрезмерными. – PhillipH
@PhillipH На типичном современном компьютере с, скажем, 8 ядрами, вы бы в абсолютном максимуме получили ускорение 7-8x, а не 1000x. В качестве побочного примечания, другие вещи быстро становятся узким местом (например, сетевым или дисковым IO). Вам лучше профилировать свой код, чтобы узнать, почему ваш синтаксический анализ длится так долго и исправить это. –