我正在尝试提高某些 UI 自动化操作的速度。我偶然发现了(不是很好)记录的缓存可能性。
据我所知,整个操作(如果你有一个大的 GUI 树)非常慢,因为对于每个函数调用都必须有一个进程更改(有点像进入内核模式,我想,速度方面?!)。所以..缓存来了。
只需告诉函数缓存一个元素及其子元素,然后闪电般地处理它。 (据我了解,您只有一次上下文更改,并一次组装您需要的所有数据。)
好主意,但是..对我来说它和未缓存的变体一样慢。我写了一些简单的测试代码,但看不到任何改进。
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
设置是:您获得一个元素并想要检查其所有(许多) sibling 。给出了不带缓存和带缓存的两种实现。
输出( Debug模式): 没有缓存的执行时间:1130 毫秒。 父缓存执行时间:1271 毫秒。
为什么这不起作用?如何改进?
感谢任何想法!!!
最佳答案
我不希望这两个循环在运行时间上有太大差异,因为在这两种情况下, parent 的 child 都必须完全走完(第一个明确地,第二个填充缓存。)我确实认为,虽然,遍历 parent.CachedChildren
数组所需的时间远低于您的初始遍历代码。那时,应该缓存元素,您可以使用它们而无需重新遍历树。
总的来说,您无法免费获得性能,因为您需要投入时间实际填充缓存才能发挥作用。
关于c# - 将缓存与 AutomationElements 一起使用不会给我加速 - 预期或错误的用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6032497/