Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Caching with AutomationElements does not give me a speedup - intended or wrong usage?

I am trying to increase the speed of some UI Automation operations. I stumbled across the (not so well) documented caching possibility.

From what I have understood, the whole operation (if you have a large GUI-tree) is so slow, because for every single function call there has to be a process-change (kind of like going to kernel-mode, I suppose, speed-wise?!). So.. in comes caching.

Simply tell the function to cache an element and its children, and then work on it lightning-fast. (From what I understand, you only have one context-change, and assemble all the data you need in one go.)

Good idea, but.. it is just as slow for me as the uncached variation. I wrote some simple testcode, and could not see an improvement.

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

The setup is: you get an element and want to check on all its (many) siblings. Both implementations, without and with cache, are given.

The output (debug mode): Execution time without cache: 1130 ms. Execution time parentcache: 1271 ms.

Why is this not working? How to improve?

Thanks for any ideas!!!

like image 390
Andreas Reiff Avatar asked Nov 18 '25 23:11

Andreas Reiff


1 Answers

I would not expect the two loops to differ much in their running time, since in both cases the parent's children must be fully walked (in the first explicitly, and in the second to populate the cache.) I do think, though, that the time required for looping through the parent.CachedChildren array is much lower than your initial walk code. At that point, the elements should be cached, and you can use them without re-walking the tree.

The general point is that you can't get performance for free, since you need to invest the time to actually populate the cache before it becomes useful.

like image 89
dlev Avatar answered Nov 20 '25 13:11

dlev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!