改进枚举性能

枚举往往使用大量系统资源。 因此,如果计划对大型组执行枚举,则应尝试优化 WMI 枚举过程。 脚本还可以使用查询来避免在具有大型集的“For each....Next”操作中性能下降。 有关详细信息,请参阅查询 WMI

以下过程介绍如何改进枚举性能。

改进枚举性能

  1. 设置 lFlags 参数以允许半同步返回数据,其枚举器在传送 WMI 时会丢弃每个项。 有关详细信息,请参阅调用方法

    以下 C++ 代码示例演示如何使用 WBEM_FLAG_RETURN_IMMEDIATE 和 WBEM_FLAG_FORWARD_ONLY 标志。

    WBEM_FLAG_RETURN_IMMEDIATE | WBEM_FLAG_FORWARD_ONLY

    在 VBScript 或 Visual Basic 中,使用 WbemFlagEnum 中的脚本标志 WbemFlagReturnImmediately 和 WbemFlagForwardOnly。 这些标志的组合值为十进制的 48。

    脚本和参数标志会导致以下行为:

    • WBEM_FLAG_RETURN_IMMEDIATE 或 wbemFlagReturnImmediately 标志请求半同步行为。 创建枚举器的调用会立即返回。 然后,可以开始遍历收到的对象集。
    • WBEM_FLAG_FORWARD_ONLY 标志或 wbemFlagForwardOnly 标志会请求无法回退的枚举器。 也就是说,在查看对象后,WMI 可以释放该对象。

    在枚举较大且应用程序速度非常快的情况下,使用具有半同步处理的只进枚举器允许 WMI 保留更少的对象,从而显著增加响应时间和内存性能。

    以下 VBScript 代码示例演示如何使用组合的 wbemFlagReturnImmediately 和 wbemFlagForwardOnly 标志进行调用,以从事件日志中获取事件集合。

    Set Events = GetObject("winmgmts:").ExecQuery _
         ("SELECT * FROM Win32_NTLogEvent " _
          & "WHERE Logfile = 'System'",,48)
    
  2. 尽可能避免在 C++ 或 SWbemServices.InstancesOf 中使用 CreateInstanceEnum,改为使用 ExecQuery。

    ExecQuery 方法使用数据库技术查询 WMI,而 CreateInstanceEnumSWbemServices.InstancesOf 枚举 WMI 对象。 具体而言,ExecQuery 可以请求枚举方法无法请求的特定数据子集。

    由于某些提供程序没有查询功能,因此 WMI 提供了“后筛选器”功能,允许 WMI 丢弃不符合查询规范的实例。 特定提供程序是否利用此功能取决于提供程序作者。

  3. 试验不同的查询,以确定哪种查询可提供最佳性能。

    例如,WMI 很少有效地处理具有 Prop1 < "x" 形式的 WHERE 子句的查询。 相比之下,WMI 通常会有效地处理 KeyProp1 = "x" 格式的查询。

有关详细信息,请参阅枚举 WMI