-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Improving performance of Import-CSV #7413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a4edcc0
3cd7d31
868359c
35764e4
d3c5f22
dd60f89
b9dd796
28b026f
5456685
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2592,7 +2592,10 @@ private readonly ConcurrentDictionary<string, object> _typeConverters | |
|
|
||
| // this is used to throw errors when updating a shared TypeTable. | ||
| internal readonly bool isShared; | ||
| private List<string> _typeFileList; | ||
| private readonly List<string> _typeFileList; | ||
|
|
||
| // The member factory is cached to avoid allocating Func<> delegates on each call | ||
| private readonly Func<string, ConsolidatedString, PSMemberInfoInternalCollection<PSMemberInfo>> _memberFactoryFunc; | ||
|
|
||
| // This holds all the type information that is in the typetable | ||
| // Holds file name if types file was used to update the types | ||
|
|
@@ -3392,6 +3395,7 @@ internal TypeTable(bool isShared) | |
| { | ||
| this.isShared = isShared; | ||
| _typeFileList = new List<string>(); | ||
| _memberFactoryFunc = MemberFactory; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the filed
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. You are trying to avoid constructing a There are 4 constructors for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, if would be helpful to add a comment to the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @daxian-dbw Done. Yes, I profiled allocations and found that this was called so frequently, and generated lots of short lived delegates.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch with the ctors - I misread the code and thought they all delegated to a single one. They do now. |
||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -3461,16 +3465,13 @@ public static List<String> GetDefaultTypeFiles() | |
| /// 1. There were errors loading TypeTable. Look in the Errors property to get | ||
| /// detailed error messages. | ||
| /// </exception> | ||
| internal TypeTable(IEnumerable<string> typeFiles, AuthorizationManager authorizationManager, PSHost host) | ||
| internal TypeTable(IEnumerable<string> typeFiles, AuthorizationManager authorizationManager, PSHost host) : this(isShared: true) | ||
| { | ||
| if (typeFiles == null) | ||
| { | ||
| throw PSTraceSource.NewArgumentNullException("typeFiles"); | ||
| } | ||
|
|
||
| isShared = true; | ||
|
|
||
| _typeFileList = new List<string>(); | ||
| ConcurrentBag<string> errors = new ConcurrentBag<string>(); | ||
| foreach (string typefile in typeFiles) | ||
| { | ||
|
|
@@ -3510,13 +3511,10 @@ internal Collection<String> GetSpecificProperties(ConsolidatedString types) | |
| var retValueTable = new HashSet<string>(StringComparer.OrdinalIgnoreCase); | ||
| foreach (string type in types) | ||
| { | ||
| PSMemberInfoInternalCollection<PSMemberInfo> typeMembers; | ||
| if (!_extendedMembers.TryGetValue(type, out typeMembers)) | ||
| if (!_extendedMembers.TryGetValue(type, out var typeMembers)) | ||
| continue; | ||
| PSMemberSet settings = typeMembers[PSStandardMembers] as PSMemberSet; | ||
| if (settings == null) | ||
| continue; | ||
| PSPropertySet typeProperties = settings.Members[PropertySerializationSet] as PSPropertySet; | ||
| PSPropertySet typeProperties = settings?.Members[PropertySerializationSet] as PSPropertySet; | ||
| if (typeProperties == null) | ||
| continue; | ||
| foreach (string reference in typeProperties.ReferencedPropertyNames) | ||
|
|
@@ -3551,64 +3549,70 @@ internal PSMemberInfoInternalCollection<T> GetMembers<T>(ConsolidatedString type | |
| return PSObject.TransformMemberInfoCollection<PSMemberInfo, T>(GetMembers(types)); | ||
| } | ||
|
|
||
| private PSMemberInfoInternalCollection<PSMemberInfo> GetMembers(ConsolidatedString types) | ||
| internal PSMemberInfoInternalCollection<PSMemberInfo> GetMembers(ConsolidatedString types) | ||
| { | ||
| if ((types == null) || string.IsNullOrEmpty(types.Key)) | ||
| { | ||
| return new PSMemberInfoInternalCollection<PSMemberInfo>(); | ||
| } | ||
| PSMemberInfoInternalCollection<PSMemberInfo> result = _consolidatedMembers.GetOrAdd(types.Key, k => | ||
|
|
||
| PSMemberInfoInternalCollection<PSMemberInfo> result = _consolidatedMembers.GetOrAdd(types.Key, _memberFactoryFunc, types); | ||
| return result; | ||
| } | ||
|
|
||
| private PSMemberInfoInternalCollection<PSMemberInfo> MemberFactory(string k, ConsolidatedString types) | ||
| { | ||
| var retValue = new PSMemberInfoInternalCollection<PSMemberInfo>(); | ||
| for (int i = types.Count - 1; i >= 0; i--) | ||
| { | ||
| var retValue = new PSMemberInfoInternalCollection<PSMemberInfo>(); | ||
| for (int i = types.Count - 1; i >= 0; i--) | ||
| if (!_extendedMembers.TryGetValue(types[i], out var typeMembers)) | ||
| { | ||
| PSMemberInfoInternalCollection<PSMemberInfo> typeMembers; | ||
| if (!_extendedMembers.TryGetValue(types[i], out typeMembers)) | ||
| continue; | ||
| } | ||
|
|
||
| foreach (PSMemberInfo typeMember in typeMembers) | ||
| { | ||
| PSMemberInfo currentMember = retValue[typeMember.Name]; | ||
| // If the member was not present, we add it | ||
| if (currentMember == null) | ||
| { | ||
| retValue.Add(typeMember.Copy()); | ||
| continue; | ||
| } | ||
| foreach (PSMemberInfo typeMember in typeMembers) | ||
|
|
||
| // There was a currentMember with the same name as typeMember | ||
| PSMemberSet currentMemberAsMemberSet = currentMember as PSMemberSet; | ||
| PSMemberSet typeMemberAsMemberSet = typeMember as PSMemberSet; | ||
| // if we are not in a memberset inherit members situation we just replace | ||
| // the current member with the new more specific member | ||
| if (currentMemberAsMemberSet == null || typeMemberAsMemberSet == null || | ||
| !typeMemberAsMemberSet.InheritMembers) | ||
| { | ||
| PSMemberInfo currentMember = retValue[typeMember.Name]; | ||
| // If the member was not present, we add it | ||
| if (currentMember == null) | ||
| { | ||
| retValue.Add(typeMember.Copy()); | ||
| continue; | ||
| } | ||
| // There was a currentMember with the same name as typeMember | ||
| PSMemberSet currentMemberAsMemberSet = currentMember as PSMemberSet; | ||
| PSMemberSet typeMemberAsMemberSet = typeMember as PSMemberSet; | ||
| // if we are not in a memberset inherit members situation we just replace | ||
| // the current member with the new more specific member | ||
| if (currentMemberAsMemberSet == null || typeMemberAsMemberSet == null || | ||
| !typeMemberAsMemberSet.InheritMembers) | ||
| retValue.Remove(typeMember.Name); | ||
| retValue.Add(typeMember.Copy()); | ||
|
||
| continue; | ||
| } | ||
|
|
||
| // We are in a MemberSet InheritMembers situation, so we add the members in | ||
| // typeMembers to the existing memberset. | ||
| foreach (PSMemberInfo typeMemberAsMemberSetMember in typeMemberAsMemberSet.Members) | ||
| { | ||
| if (currentMemberAsMemberSet.Members[typeMemberAsMemberSetMember.Name] == null) | ||
| { | ||
| retValue.Remove(typeMember.Name); | ||
| retValue.Add(typeMember.Copy()); | ||
| ((PSMemberInfoIntegratingCollection<PSMemberInfo>)currentMemberAsMemberSet.Members) | ||
| .AddToTypesXmlCache(typeMemberAsMemberSetMember, false); | ||
| continue; | ||
| } | ||
| // We are in a MemberSet InheritMembers situation, so we add the members in | ||
| // typeMembers to the existing memberset. | ||
| foreach (PSMemberInfo typeMemberAsMemberSetMember in typeMemberAsMemberSet.Members) | ||
| { | ||
| if (currentMemberAsMemberSet.Members[typeMemberAsMemberSetMember.Name] == null) | ||
| { | ||
| ((PSMemberInfoIntegratingCollection<PSMemberInfo>)currentMemberAsMemberSet.Members) | ||
| .AddToTypesXmlCache(typeMemberAsMemberSetMember, false); | ||
| continue; | ||
| } | ||
| // there is a name conflict, the new member wins. | ||
| Diagnostics.Assert(!typeMemberAsMemberSetMember.IsHidden, | ||
| "new member in types.xml cannot be hidden"); | ||
| currentMemberAsMemberSet.InternalMembers.Replace(typeMemberAsMemberSetMember); | ||
| } | ||
|
|
||
| // there is a name conflict, the new member wins. | ||
| Diagnostics.Assert(!typeMemberAsMemberSetMember.IsHidden, | ||
| "new member in types.xml cannot be hidden"); | ||
| currentMemberAsMemberSet.InternalMembers.Replace(typeMemberAsMemberSetMember); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return retValue; | ||
| }); | ||
| return result; | ||
| return retValue; | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daxian-dbw
varis bad readable here. And we should excludetypesXmlMember(used once).@powercode Thanks for excluding transformation whole collection. Good catch!