[英]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);
}
}
}
這可能會大大縮短時間。 但是如果你真的想找到可能的最佳性能,你需要直接使用DirectorySearcher
和DirectoryEntry
。 PrincipalSearcher
/ UserPrincipal
類無論如何都在后台使用它們,但是您對后台發生的事情失去了很多控制,這就是性能的關鍵。 為了獲得最佳性能,您需要減少:
我寫了幾篇關於這個主題的文章,可以幫助你解決這個問題,如果你想走這條路:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.