簡體   English   中英

如何提高方法的性能

[英]How can I improve the performance for a method

我寫了一個函數來獲取來自 AD 的成員的所有組:

public static void getGroupsWithUsers() {
        String currentDomain = Domain.GetCurrentDomain().ToString();

        using (PrincipalContext context = new PrincipalContext(ContextType.Domain, currentDomain))
        {
            using (PrincipalSearcher searcher = new PrincipalSearcher(new UserPrincipal(context)))
            {

                foreach (var result in searcher.FindAll())
                {
                    DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
                    var SID = WindowsIdentity.GetCurrent().User.ToString();


                    // find a user
                    UserPrincipal user = UserPrincipal.FindByIdentity(context, de.Properties["samAccountName"].Value.ToString());

                    if (user != null)
                    {
                        // get the user's groups
                        var groups = user.GetAuthorizationGroups();

                        foreach (GroupPrincipal group in groups)
                        {
                            Console.WriteLine("User: " + user + " is in Group: " + group);
                        }


                    }
                }
            }
        }

    } 

少量數據的執行時間約為 1.5 秒。 我是否可以進行任何改進以更快地獲得該方法? 我問是因為如果我為 100 萬用戶或組執行該功能,它將永遠運行。

嘗試拆分操作:首先 - 獲取字符串生成器的信息,其次 - 打印它。

像這樣

public static void getGroupsWithUsers() 
{
    String currentDomain = Domain.GetCurrentDomain().ToString();
    var stringBuilder = new StringBuilder();

    using (PrincipalContext context = new PrincipalContext(ContextType.Domain, currentDomain))
    {
        using (PrincipalSearcher searcher = new PrincipalSearcher(new UserPrincipal(context)))
        {
            foreach (var result in searcher.FindAll())
            {
                DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
                var SID = WindowsIdentity.GetCurrent().User.ToString();

                // find a user
                UserPrincipal user = UserPrincipal.FindByIdentity(context, de.Properties["samAccountName"].Value.ToString());

                if (user != null)
                {
                    // get the user's groups
                    var groups = user.GetAuthorizationGroups();

                    foreach (GroupPrincipal group in groups)
                    {
                        stringBuilder.AppendLine($"User: {user} is in Group: {group}");
                    }
                }
            }
        }
    }

    string result = stringBuilder.Length > 0
        ? stringBuilder.ToString()
        : "No users were found";

    Console.WriteLine(result);
} 

你的大部分問題是你在循環中做什么。 您正在獲取搜索結果,將其轉換為DirectoryEntry ,然后返回到網絡以查找您剛剛找到的帳戶。

PrincipalSearcher.FindAll方法返回Principal對象的集合,您可以將這些對象強制轉換為您知道的類型。 在這種情況下,您知道它只會返回用戶,因此您可以在循環中將結果轉換為UserPrincipal

您還分配了一個您沒有使用的SID變量(盡管這可能不會花費任何大量時間)。

旁注:這里不需要currentDomain變量,因為如果您使用ContextType.Domain創建一個PrincipalContext並且沒有域名,它將自動使用當前域。

所以你的代碼可以簡化為:

using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
using (PrincipalSearcher searcher = new PrincipalSearcher(new UserPrincipal(context)))
{

    foreach (UserPrincipal user in searcher.FindAll())
    {
        // get the user's groups
        var groups = user.GetAuthorizationGroups();

        foreach (GroupPrincipal group in groups)
        {
            Console.WriteLine("User: " + user + " is in Group: " + group);
        }
    }
}

這可能會大大縮短時間。 但是如果你真的想找到可能的最佳性能,你需要直接使用DirectorySearcherDirectoryEntry PrincipalSearcher / UserPrincipal類無論如何都在后台使用它們,但是您對后台發生的事情失去了很多控制,這就是性能的關鍵。 為了獲得最佳性能,您需要減少:

  1. 網絡請求的數量,以及
  2. 有多少數據被發回。

我寫了幾篇關於這個主題的文章,可以幫助你解決這個問題,如果你想走這條路:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM