将缓存与 AutomationElements 一起使用不会给我一个加速 - 有意或错误的用法
本文关键字:加速 一个 用法 错误 一起 AutomationElements 缓存 | 更新日期: 2023-09-27 17:56:47
我正在尝试提高某些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
设置是:你得到一个元素,并想检查它的所有(许多)兄弟姐妹。给出了两种实现,不带缓存和带缓存。
输出(调试模式):无缓存的执行时间:1130 毫秒。执行时间父缓存:1271 毫秒。
为什么这不起作用?如何改进?
感谢您的任何想法!!
我不希望这两个循环在运行时间上相差太大,因为在这两种情况下,父循环都必须完全遍历(在第一个显式中,在第二个中填充缓存。不过,我确实认为,循环遍历parent.CachedChildren
数组所需的时间远低于最初的步行代码。此时,元素应该被缓存,并且无需重新遍历树即可使用它们。
一般的一点是,您无法免费获得性能,因为您需要投入时间来实际填充缓存
实际上,最近我找到了时间再次检查它,并且还针对不同的UI元素进行了检查。为了使缓存更快,首先必须指定所有(且仅)所需的元素。例如,如果您查看包含 100 个元素的 ComboBox 或类似的东西,例如一个非常复杂的 GUI,其中许多元素位于同一层次结构级别 - 并且您实际上需要来自所有这些元素的数据,则存在真正的性能差异。所以。。缓存不是所有解决方案,而是一种必须应用的性能优化工具。了解情况,要求和内部工作。顺便说一句,谈到性能,我发现每次 .current 访问 UI 元素大约需要 20 毫秒,因此对于复杂的操作,这确实可以达到一个重要的时间。