【问题标题】:Can I speed up this query to retrieve all computers on the domain?我可以加快此查询以检索域中的所有计算机吗?
【发布时间】:2013-06-26 20:16:24
【问题描述】:

我编写了一个帮助类来获取域中的所有计算机,但它有点慢。虽然返回了 128 个对象,但我仍然想加快速度。有什么想法吗?

public class DomainBrowser
{
    private const string Computer = "computer";

    public string Domain { get; private set; }

    public DomainBrowser(string domain)
    {
        this.Domain = domain.ToLower();
    }

    /// <summary>
    /// This method returns a list of the computer names available in the current domain.
    /// </summary>
    /// <returns></returns>
    public List<string> GetComputers()
    {
        var winDirEntries = new DirectoryEntry("WinNT:");

        var computers = (from DirectoryEntry domain in winDirEntries.Children
                         where domain.Name.ToLower() == this.Domain
                         from DirectoryEntry pc in domain.Children
                         where pc.SchemaClassName.ToLower().Contains(Computer)
                         select pc.Name).ToList();

        return computers;
    }
}

【问题讨论】:

    标签: c# .net performance directoryentry


    【解决方案1】:

    这里最大的问题之一是所有ToLower() 调用。字符串是不可变的,因此它们的每次更改(例如将它们更改为代码示例中所见的小写)都会创建一个新对象。此外,字符串小写所涉及的逻辑比您想象的要昂贵,因为它必须考虑诸如当前文化设置之类的事情。

    为了减少开销,尽量不要更改字符串引用,而是将它们与不区分大小写进行比较:

    var computers = (from DirectoryEntry domain in winDirEntries.Children
                         where string.Equals(domain.Name, this.Domain, StringComparison.OrdinalIgnoreCase)
                         from DirectoryEntry pc in domain.Children
                         where pc.SchemaClassName.IndexOf(Computer, StringComparison.OrdinalIgnoreCase) != -1
                         select pc.Name).ToList();
    

    请注意,我必须将 string.Compare 更改为 string.IndexOf,因为 Compare 没有不区分大小写的重载。

    【讨论】:

    • 你说的有道理,所以我试了一下。使用Stopwatch 类,将调用更改为ToLower() 会使其始终变慢。我使用ToLower() 在 19-20 秒内获得结果,而使用您建议的更改,我在 21-24 秒内得到结果。
    • 通过更多测试,使用IndexOf 似乎是您建议的瓶颈。看起来忽略这个案子也不会有很大的不同。也许在更大的集合中它会更有效,但对于 1-200 个结果,我得到原始代码的速度更快。
    • 这非常违反直觉。他们在检索域信息时的网络延迟是否可能是您的主要延迟?
    • 可能是这样。我现在正在使用 VPN,我可能会在现场进行测试。
    • 这几乎肯定是你的问题。
    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 2017-02-11
    • 1970-01-01
    • 2012-06-27
    相关资源
    最近更新 更多