我面临的情况是,仅仅使用C#遍历MSHTML元素的速度非常慢。这里是通过document.all三次迭代的迭代的一个小例子。我们有空白WPF应用程序和WebBrowser控件命名的浏览器:HTML遍历速度很慢
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
Browser.LoadCompleted += DocumentLoaded;
Browser.Navigate("http://google.com");
}
private IHTMLElementCollection _items;
private void DocumentLoaded(object sender, NavigationEventArgs e)
{
var dc = (HTMLDocument)Browser.Document;
_items = dc.all;
Test();
Test();
Test();
}
private void Test()
{
var sw = new Stopwatch();
sw.Start();
int i;
for (i = 0; i < _items.length; i++)
{
_items.item(i);
}
sw.Stop();
Debug.WriteLine("Items: {0}, Time: {1}", i, sw.Elapsed);
}
}
输出是:
Items: 274, Time: 00:00:01.0573245
Items: 274, Time: 00:00:00.0011637
Items: 274, Time: 00:00:00.0006619
1条2线之间的性能差异是可怕的。我试图用非托管的C++和COM重写相同的代码,并且完全没有性能问题,非托管代码运行速度提高了1200倍。不幸的是,非托管不是一种选择,因为真正的项目比简单的迭代更复杂。
据我所知,第一次运行时为每个被引用的HTML元素(COM对象)创建RCW。但它可以这么慢吗?每秒300个项目,3,2 GHz CPU的100%核心负载。上面的代码的
性能分析:
您是否尝试过使用HTML敏捷性包呢? – svick
不,因为这是第三方,我们不需要在项目中'解析'HTML,所以我们需要节点作为对象。 – Dizzy
我不明白区别。 MSHTML确实解析了HTML和Html Agility Pack确实会为您提供节点作为对象。 – svick