3

一部のUIオートメーション操作の速度を上げようとしています。私は(あまりよくない)文書化されたキャッシュの可能性に出くわしました。

私が理解したことから、操作全体(大きなGUIツリーがある場合)は非常に遅いです。なぜなら、関数呼び出しごとにプロセスを変更する必要があるからです(カーネルモードに移行するようなものだと思います。速度的に?!)。だから..キャッシングがやってくる。

要素とその子をキャッシュするように関数に指示するだけで、非常に高速に処理できます。(私が理解していることから、コンテキスト変更は1つだけであり、必要なすべてのデータを一度にアセンブルします。)

良い考えですが、キャッシュされていないバリエーションと同じくらい遅いです。簡単なテストコードをいくつか書きましたが、改善は見られませんでした。

AutomationElement ae; // element whose siblings are to be examined, thre are quite a few siblings
AutomationElement sibling;

#region non-cached
watch.Start();
for (int i = 0; i < 10; ++i)
{
    sibling = TreeWalker.RawViewWalker.GetFirstChild(TreeWalker.RawViewWalker.GetParent(ae));
    while (sibling != null)
    {
        sibling = TreeWalker.RawViewWalker.GetNextSibling(sibling);
    }
}
watch.Stop();
System.Diagnostics.Debug.WriteLine("Execution time without cache: " + watch.ElapsedMilliseconds + " ms.");
#endregion

#region cached
watch.Reset();
watch.Start();

CacheRequest cacheRequest = new CacheRequest();
cacheRequest.TreeScope = TreeScope.Children | TreeScope.Element; // for testing I chose a minimal set
AutomationElement parent;

for (int j = 0; j < 10; ++j)
{
    using (cacheRequest.Activate())
    {
        parent = TreeWalker.RawViewWalker.GetParent(ae, cacheRequest);
    }
    int cnt = parent.CachedChildren.Count;
    for (int i = 0; i < cnt; ++i)
    {
        sibling = parent.CachedChildren[i];
    }
}
watch.Stop();
System.Diagnostics.Debug.WriteLine("Execution time parentcache: " + watch.ElapsedMilliseconds + " ms.");
#endregion

設定は次のとおりです。要素を取得し、そのすべての(多くの)兄弟をチェックしたい。キャッシュなしとキャッシュありの両方の実装が示されています。

出力(デバッグモード):キャッシュなしの実行時間:1130ミリ秒。実行時間parentcache:1271ミリ秒。

なぜこれが機能しないのですか?改善方法?

アイデアをありがとう!!!

4

2 に答える 2

2

どちらの場合も、親の子を完全にウォークする必要があるため(最初のループでは明示的に、2番目のループではキャッシュにデータを入力するため)、2つのループの実行時間に大きな違いはないと思います。配列をループするのに必要な時間parent.CachedChildrenは、最初のウォークコードよりもはるかに短くなります。その時点で、要素はキャッシュされているはずであり、ツリーを再度歩くことなくそれらを使用できます。

一般的なポイントは、キャッシュが有用になる前に実際にキャッシュにデータを投入するために時間を費やす必要があるため、無料でパフォーマンスを得ることができないということです。

于 2011-05-17T14:47:38.950 に答える
0

実際、最近、私はそれをもう一度チェックする時間を見つけました。また、さまざまなUI要素に対してもチェックしました。キャッシングを高速化するには、最初に必要なすべての(そして唯一の)要素を指定する必要があります。たとえば、100個の要素が内部にあるComboBoxなど、同じ階層レベルに多数の要素がある非常に複雑なGUIを見ると、実際のパフォーマンスの違いがあります。実際には、それらすべてのデータが必要です。したがって、キャッシングはすべてのソリューションではなく、状況、要件、および内部動作に関する知識を適用する必要があるパフォーマンス最適化ツールです。ところで、パフォーマンスについて話すと、UI要素への現在のアクセスにはそれぞれ約20ミリ秒かかることがわかりました。したがって、複雑な操作の場合、これは実際にかなりの時間に達する可能性があります。

于 2012-06-26T09:45:29.567 に答える