3

C#を使用してMSHTML要素を単純に反復処理するのは非常に遅いことに直面しました。これは、 document.allコレクションを3回繰り返す小さな例です。空白のWPFアプリケーションとBrowserという名前のWebBrowserコントロールがあります。

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倍高速に実行されます。残念ながら、実際のプロジェクトは単純な反復よりも複雑であるため、管理されていない状態にすることはできません。

ランタイムが、COMオブジェクトである参照されるHTML要素ごとにRCWを初めて作成することを理解しています。しかし、それはそんなに遅いのでしょうか?毎秒300アイテム、3,2 GHz CPUの100%コア負荷。

上記のコードのパフォーマンス分析: パフォーマンス分析

4

2 に答える 2

1

document.all.item(index) の代わりに for each を使用してすべての要素コレクションを列挙します (C++ に切り替える場合は IHTMLElementCollection::get__newEnum を使用します)。

推奨読書: IE + JavaScript パフォーマンスに関する推奨事項 - パート 1

于 2013-02-02T22:17:18.163 に答える
0

パフォーマンス低下の原因は、コレクション アイテムが MSHTML 相互運用機能アセンブリで動的オブジェクトとして定義されていることです。

public interface IHTMLElementCollection : IEnumerable
{
    ...
    [DispId(0)]
    dynamic item(object name = Type.Missing, object index = Type.Missing);
    ...
}

IDispatch オブジェクトを返すようにそのインターフェイスを書き直すと、ラグはなくなります。

public interface IHTMLElementCollection : IEnumerable
{
    ...
    [DispId(0)]
    [return: MarshalAs(UnmanagedType.IDispatch)]
    object item(object name = Type.Missing, object index = Type.Missing);
    ...
}

新しい出力:

Items: 246, Time: 00:00:00.0034520
Items: 246, Time: 00:00:00.0029398
Items: 246, Time: 00:00:00.0029968
于 2013-02-03T09:09:44.417 に答える