Я пытаюсь распараллелить мой инструмент для разбора веб-страниц, но прирост скорости кажется очень минимальным. У меня i7-2600K (8 ядер с гиперпоточностью).
Вот код, который покажет вам идею. Я только показываю Parallel.ForEach
, но вы поняли:
List<string> AllLinks = this.GetAllLinks();
ConcurrentDictionary<string, Topic> AllTopics = new ConcurrentDictionary<string, Topic> ( );
int count = 0;
Stopwatch sw = new Stopwatch ( );
sw.Start ( );
Parallel.ForEach ( AllLinks, currentLink =>
{
Topic topic = this.ExtractTopicData ( currentLink );
this.AllTopics.TryAdd ( currentLink, topic );
++count;
if ( count > 50 )
{
Console.WriteLine ( sw.ElapsedMilliseconds );
count = 0;
}
} );
Я получаю эти тайминги:
Standard foreach loop:
24582
59234
82800
117786
140315
2 links per second
Paralel.For:
21902
31649
41168
49817
59321
5 links per second
Paralel.ForEach:
10217
20401
39056
49220
58125
5 links per second
Во-первых, почему время запуска значительно ниже в Parallel.For
?
Кроме этого, параллельные циклы дают мне 2,5-кратную скорость по сравнению со стандартным циклом foreach. Это нормально?
Есть ли настройка, которую я могу установить, чтобы параллельные циклы могли использовать все ядра?
EDIT:
Вот в значительной степени то, что делает ExtractTopicData
:
HtmlAgilityPack.HtmlWeb web = new HtmlWeb ( );
HtmlAgilityPack.HtmlDocument doc = web.Load ( url );
IEnumerable<HtmlNode> links = doc.DocumentNode.SelectNodes ( "//*[@id=\"topicDetails\"]" );
var topic = new Topic();
foreach ( var link in links )
{
//parse the link data
}