如何使用Parallel.For/ForEach获得最佳性能?(包括执行时间)我正在尝试并行化我的网络解析工具,但速度增益似乎非常小。我有i7-2600K(8核超线程)。这里有一些代码可以向您展示这个想法。我只展示了Parallel.ForEach但你明白了:ListAllLinks=this.GetAllLinks();ConcurrentDictionaryAllTopics=newConcurrentDictionary();整数计数=0;秒表sw=新秒表();sw.开始();平行线。ForEach(AllLinks,currentLink=>{Topictopic=this.ExtractTopicData(currentLink);this.AllTopics.TryAdd(currentLink,topic);++count;if(count>50){Console.WriteLine(sw.ElapsedMilliseconds);计数=0;}});我我得到:接头标准:2458259234828001177861403152链接每秒链条链路:21902316494116494116849817593215Parallel的“启动”时间。要慢得多。除此之外,并行循环提供比标准foreach循环快2.5倍的速度。这是正常的吗?有没有我可以设置的设置,以便并行循环可以使用所有内核?编辑:这几乎就是ExtractTopicData所做的:HtmlAgilityPack.HtmlWebweb=newHtmlWeb();HtmlAgilityPack.HtmlDocumentdoc=web.Load(url);IEnumerablelinks=doc.DocumentNode.SelectNodes("//*[@id="topicDetails"]");vartopic=newTopic();foreach(varlinkinlinks){//解析链接数据}简要阅读HtmlAgilityPack.HtmlWeb确认它正在使用同步WebRequestAPI。因此,您将长时间运行的任务放入线程池(通过并行)。ThreadPool专为短期操作而设计,可快速将线程返回到池中。阻塞IO是一个很大的禁忌。鉴于ThreadPool不愿意启动新线程(因为它不是为这种用途而设计的),您将受到这种行为的限制。异步获取您的Web内容(请参阅此处和此处了解要使用的正确API,您必须自己进一步调查...),这样您就不会将ThreadPool与阻塞任务捆绑在一起。然后,您可以将解码后的响应提供给HtmlAgilityPack进行解析。如果真的想提高性能,还需要考虑WebRequest不能进行异步DNS查找。IMO这是WebRequest设计中的一个可怕缺陷。在该方法变为异步之前,BeginGetResponse方法需要完成一些同步设置任务(例如,DNS解析、代理检测和TCP套接字连接)。它使高性能下载成为真正的PITA。大约在这个时候,您可能会考虑编写自己的HTTP库,以便可以在不阻塞的情况下执行所有操作(从而使ThreadPool挨饿)。此外,在浏览网页时获得最大吞吐量是一项棘手的工作。根据我的经验,您可以获得正确的代码,然后通过它必须经过的路由设备进行工作。许多家用路由器根本无法胜任这项工作。以上就是C#学习教程:HowtouseParallel.For/ForEachtogetmaximumperformance?(含表演时间)所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
