From a4edcc0e89a6e47e24406f1d929112cca1ca481f Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Tue, 31 Jul 2018 15:30:35 +0200 Subject: [PATCH 1/9] Optimization NoteProperty addition of imported csv props. --- .../commands/utility/CSVCommands.cs | 13 ++++++++----- .../engine/MshMemberInfo.cs | 9 +++++++++ .../engine/MshObject.cs | 11 +++++++++++ .../engine/runtime/Binding/Binders.cs | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index cbcded90063..4187f13cec8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1278,6 +1278,7 @@ internal void ReadHeader() { _alreadyWarnedUnspecifiedName = alreadyWriteOutWarning; ReadHeader(); + var prevalidated = false; while (true) { Collection values = ParseNextRecord(); @@ -1290,7 +1291,8 @@ internal void ReadHeader() continue; } - PSObject result = BuildMshobject(TypeName, Header, values, _delimiter); + PSObject result = BuildMshobject(TypeName, Header, values, _delimiter, prevalidated); + prevalidated = true; _cmdlet.WriteObject(result); } alreadyWriteOutWarning = _alreadyWarnedUnspecifiedName; @@ -1611,10 +1613,10 @@ private Collection private PSObject - BuildMshobject(string type, IList names, Collection values, char delimiter) + BuildMshobject(string type, IList names, Collection values, char delimiter, bool preValidated = false) { //string[] namesarray = null; - PSObject result = new PSObject(); + PSObject result = new PSObject(names.Count); char delimiterlocal = delimiter; int unspecifiedNameIndex = 1; for (int i = 0; i <= names.Count - 1; i++) @@ -1635,7 +1637,8 @@ private Collection { value = values[i]; } - result.Properties.Add(new PSNoteProperty(name, value)); + + result.Properties.Add(new PSNoteProperty(name, value), preValidated); } if (!_alreadyWarnedUnspecifiedName && unspecifiedNameIndex != 1) @@ -1644,7 +1647,7 @@ private Collection _alreadyWarnedUnspecifiedName = true; } - if (type != null && type.Length > 0) + if (!string.IsNullOrEmpty(type)) { result.TypeNames.Clear(); result.TypeNames.Add(type); diff --git a/src/System.Management.Automation/engine/MshMemberInfo.cs b/src/System.Management.Automation/engine/MshMemberInfo.cs index 35c6acecedd..90131952999 100644 --- a/src/System.Management.Automation/engine/MshMemberInfo.cs +++ b/src/System.Management.Automation/engine/MshMemberInfo.cs @@ -4019,6 +4019,14 @@ internal PSMemberInfoInternalCollection() _members = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); } + /// + /// Constructs this collection with an initial capacity + /// + internal PSMemberInfoInternalCollection(int capacity) + { + _members = new OrderedDictionary(capacity, StringComparer.OrdinalIgnoreCase); + } + private void Replace(T oldMember, T newMember) { _members[newMember.Name] = newMember; @@ -5011,6 +5019,7 @@ public void Dispose() { } } } + #endregion Member collection classes and its auxiliary classes } diff --git a/src/System.Management.Automation/engine/MshObject.cs b/src/System.Management.Automation/engine/MshObject.cs index 53a996d5d69..78aa14e3906 100644 --- a/src/System.Management.Automation/engine/MshObject.cs +++ b/src/System.Management.Automation/engine/MshObject.cs @@ -521,6 +521,17 @@ public PSObject() CommonInitialization(PSCustomObject.SelfInstance); } + /// + /// Initializes a new instance of PSObject with an PSCustomObject BaseObject + /// with an initial capacity for members + /// + /// The initial capacity for the instance member collection. + public PSObject(int instanceMemberCapacity) : this() + { + _instanceMembers = new PSMemberInfoInternalCollection(instanceMemberCapacity); + } + + /// /// Initializes a new instance of PSObject wrapping obj (accessible through BaseObject). /// diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index b10d2ecac91..f4ab7c73f6b 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -4848,7 +4848,7 @@ internal static void SetHasInstanceMember(string memberName) lock (binderList) { - if (!binderList.Any()) + if (binderList.Count == 0) { // Force one binder to be created if one hasn't been created already. PSGetMemberBinder.Get(memberName, (Type)null, @static: false); From 3cd7d3105e9eca917ca2338eaafd121102d7ae02 Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Wed, 1 Aug 2018 00:45:29 +0200 Subject: [PATCH 2/9] Addressing review comments. --- src/System.Management.Automation/engine/MshMemberInfo.cs | 1 - src/System.Management.Automation/engine/MshObject.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/System.Management.Automation/engine/MshMemberInfo.cs b/src/System.Management.Automation/engine/MshMemberInfo.cs index 90131952999..bebd04c1b78 100644 --- a/src/System.Management.Automation/engine/MshMemberInfo.cs +++ b/src/System.Management.Automation/engine/MshMemberInfo.cs @@ -5019,7 +5019,6 @@ public void Dispose() { } } } - #endregion Member collection classes and its auxiliary classes } diff --git a/src/System.Management.Automation/engine/MshObject.cs b/src/System.Management.Automation/engine/MshObject.cs index 78aa14e3906..cf5c4defd3d 100644 --- a/src/System.Management.Automation/engine/MshObject.cs +++ b/src/System.Management.Automation/engine/MshObject.cs @@ -531,7 +531,6 @@ public PSObject(int instanceMemberCapacity) : this() _instanceMembers = new PSMemberInfoInternalCollection(instanceMemberCapacity); } - /// /// Initializes a new instance of PSObject wrapping obj (accessible through BaseObject). /// From 868359c3c6253b32338309d8bd35ba3320d7981e Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Wed, 1 Aug 2018 13:13:20 +0200 Subject: [PATCH 3/9] Improve performance of AddToTypesXmlCache By avoiding an expensive copying of members just to check for the existance of one of them, perf is significantly increased, and allocations are reduced. --- src/System.Management.Automation/engine/MshMemberInfo.cs | 5 +++-- src/System.Management.Automation/engine/TypeTable.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/MshMemberInfo.cs b/src/System.Management.Automation/engine/MshMemberInfo.cs index bebd04c1b78..eee7d1e4df9 100644 --- a/src/System.Management.Automation/engine/MshMemberInfo.cs +++ b/src/System.Management.Automation/engine/MshMemberInfo.cs @@ -4575,8 +4575,9 @@ internal void AddToTypesXmlCache(T member, bool preValidated) TypeTable typeTable = _mshOwner.GetTypeTable(); if (typeTable != null) { - PSMemberInfoInternalCollection typesXmlMembers = typeTable.GetMembers(_mshOwner.InternalTypeNames); - if (typesXmlMembers[member.Name] != null) + var typesXmlMembers = typeTable.GetMembers(_mshOwner.InternalTypeNames); + var typesXmlMember = typesXmlMembers[member.Name]; + if (typesXmlMember is T) { throw new ExtendedTypeSystemException( "AlreadyPresentInTypesXml", diff --git a/src/System.Management.Automation/engine/TypeTable.cs b/src/System.Management.Automation/engine/TypeTable.cs index 328f4a2f67c..d4d9939cc2d 100644 --- a/src/System.Management.Automation/engine/TypeTable.cs +++ b/src/System.Management.Automation/engine/TypeTable.cs @@ -3551,7 +3551,7 @@ internal PSMemberInfoInternalCollection GetMembers(ConsolidatedString type return PSObject.TransformMemberInfoCollection(GetMembers(types)); } - private PSMemberInfoInternalCollection GetMembers(ConsolidatedString types) + internal PSMemberInfoInternalCollection GetMembers(ConsolidatedString types) { if ((types == null) || string.IsNullOrEmpty(types.Key)) { From 35764e4deba1c24663d643ef07cc583d77bab786 Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Wed, 1 Aug 2018 18:59:25 +0200 Subject: [PATCH 4/9] Additional perf work on Import-CSV Reduce allocations and GC pressure by preallocating and reusing StringBuilders and List for line parsing. Use List instead of Collection to get fewer virtual calls and better inlining. --- .../commands/utility/CSVCommands.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index 4187f13cec8..b612a85b349 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1234,10 +1234,11 @@ internal void ReadHeader() { TypeName = ReadTypeInformation(); } - + var values = new List(16); + var builder = new StringBuilder(256); while ((Header == null) && (!this.EOF)) { - Collection values = ParseNextRecord(); + ParseNextRecord(values, builder); // Trim all trailing blankspaces and delimiters ( single/multiple ). // If there is only one element in the row and if its a blankspace we dont trim it. @@ -1279,9 +1280,11 @@ internal void ReadHeader() _alreadyWarnedUnspecifiedName = alreadyWriteOutWarning; ReadHeader(); var prevalidated = false; + var values = new List(16); + var builder = new StringBuilder(256); while (true) { - Collection values = ParseNextRecord(); + ParseNextRecord(values, builder); if (values.Count == 0) break; @@ -1367,13 +1370,12 @@ private string /// /// Parsed collection of strings. /// - private Collection - ParseNextRecord() + private void + ParseNextRecord(List result, StringBuilder current) { - // Collection of strings to return - Collection result = new Collection(); + result.Clear(); // current string - StringBuilder current = new StringBuilder(); + current.Clear(); bool seenBeginQuote = false; // int i = 0; @@ -1521,8 +1523,6 @@ private Collection { result.Add(current.ToString()); } - - return result; } // If we detect a newline we return it as a string "\r", "\n" or "\r\n" @@ -1613,7 +1613,7 @@ private Collection private PSObject - BuildMshobject(string type, IList names, Collection values, char delimiter, bool preValidated = false) + BuildMshobject(string type, IList names, List values, char delimiter, bool preValidated = false) { //string[] namesarray = null; PSObject result = new PSObject(names.Count); From d3c5f22098e4df85f049d22142ef6a1e4a982658 Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Wed, 1 Aug 2018 19:15:35 +0200 Subject: [PATCH 5/9] Reducing allocations by using a preallocated value factory in TypeTable.GetMembers GetMembers(ConsolidatedString types) --- .../engine/TypeTable.cs | 98 ++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/src/System.Management.Automation/engine/TypeTable.cs b/src/System.Management.Automation/engine/TypeTable.cs index d4d9939cc2d..f06e548c3f4 100644 --- a/src/System.Management.Automation/engine/TypeTable.cs +++ b/src/System.Management.Automation/engine/TypeTable.cs @@ -2592,7 +2592,9 @@ private readonly ConcurrentDictionary _typeConverters // this is used to throw errors when updating a shared TypeTable. internal readonly bool isShared; - private List _typeFileList; + private readonly List _typeFileList; + + private readonly Func> _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 +3394,7 @@ internal TypeTable(bool isShared) { this.isShared = isShared; _typeFileList = new List(); + _memberFactoryFunc = MemberFactory; } /// @@ -3510,13 +3513,10 @@ internal Collection GetSpecificProperties(ConsolidatedString types) var retValueTable = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string type in types) { - PSMemberInfoInternalCollection 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) @@ -3557,58 +3557,64 @@ internal PSMemberInfoInternalCollection GetMembers(ConsolidatedStr { return new PSMemberInfoInternalCollection(); } - PSMemberInfoInternalCollection result = _consolidatedMembers.GetOrAdd(types.Key, k => + + PSMemberInfoInternalCollection result = _consolidatedMembers.GetOrAdd(types.Key, _memberFactoryFunc, types); + return result; + } + + private PSMemberInfoInternalCollection MemberFactory(string k, ConsolidatedString types) + { + var retValue = new PSMemberInfoInternalCollection(); + for (int i = types.Count - 1; i >= 0; i--) { - var retValue = new PSMemberInfoInternalCollection(); - for (int i = types.Count - 1; i >= 0; i--) + if (!_extendedMembers.TryGetValue(types[i], out var typeMembers)) { - PSMemberInfoInternalCollection 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)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)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; } /// From dd60f89a55a32046ac775bbd9888d2b1c7d200e7 Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Fri, 3 Aug 2018 02:38:08 +0200 Subject: [PATCH 6/9] Addressing @daxian-dbw comments --- src/System.Management.Automation/engine/TypeTable.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/TypeTable.cs b/src/System.Management.Automation/engine/TypeTable.cs index f06e548c3f4..1d626186283 100644 --- a/src/System.Management.Automation/engine/TypeTable.cs +++ b/src/System.Management.Automation/engine/TypeTable.cs @@ -2594,6 +2594,7 @@ private readonly ConcurrentDictionary _typeConverters internal readonly bool isShared; private readonly List _typeFileList; + // The member factory is cached to avoid allocating Func<> delegates on each call private readonly Func> _memberFactoryFunc; // This holds all the type information that is in the typetable @@ -3464,16 +3465,13 @@ public static List GetDefaultTypeFiles() /// 1. There were errors loading TypeTable. Look in the Errors property to get /// detailed error messages. /// - internal TypeTable(IEnumerable typeFiles, AuthorizationManager authorizationManager, PSHost host) + internal TypeTable(IEnumerable typeFiles, AuthorizationManager authorizationManager, PSHost host) : this(isShared: true) { if (typeFiles == null) { throw PSTraceSource.NewArgumentNullException("typeFiles"); } - isShared = true; - - _typeFileList = new List(); ConcurrentBag errors = new ConcurrentBag(); foreach (string typefile in typeFiles) { From b9dd796663317bf03b46e368000ad29d4365f7b8 Mon Sep 17 00:00:00 2001 From: "Gustafsson, Staffan" Date: Fri, 3 Aug 2018 17:02:31 +0200 Subject: [PATCH 7/9] Making constants of magic numbers --- .../commands/utility/CSVCommands.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index b612a85b349..d1dc7a696f3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1234,8 +1234,15 @@ internal void ReadHeader() { TypeName = ReadTypeInformation(); } - var values = new List(16); - var builder = new StringBuilder(256); + + // initial sizes of the value list and the line stringbuilder + // set to reasonable initial sizes. They may grow beyond these, + // but this will prevent a few reallocations. + const int valueCountGuestimate = 16; + const int lineLengthGuestimate = 256; + + var values = new List(valueCountGuestimate); + var builder = new StringBuilder(lineLengthGuestimate); while ((Header == null) && (!this.EOF)) { ParseNextRecord(values, builder); @@ -1370,7 +1377,7 @@ private string /// /// Parsed collection of strings. /// - private void + private void ParseNextRecord(List result, StringBuilder current) { result.Clear(); From 28b026fe7d221b6f0109ba1bb2bd2df00c5cc1f6 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 3 Aug 2018 12:37:27 -0700 Subject: [PATCH 8/9] [Feature] Also use the const values in 'Import' --- .../commands/utility/CSVCommands.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index d1dc7a696f3..42671cfc6e1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1149,6 +1149,12 @@ internal class ImportCsvHelper /// private readonly StreamReader _sr; + // Initial sizes of the value list and the line stringbuilder. + // Set to reasonable initial sizes. They may grow beyond these, + // but this will prevent a few reallocations. + private const int valueCountGuestimate = 16; + private const int lineLengthGuestimate = 256; + internal ImportCsvHelper(PSCmdlet cmdlet, char delimiter, IList header, string typeName, StreamReader streamReader) { if (cmdlet == null) @@ -1235,12 +1241,6 @@ internal void ReadHeader() TypeName = ReadTypeInformation(); } - // initial sizes of the value list and the line stringbuilder - // set to reasonable initial sizes. They may grow beyond these, - // but this will prevent a few reallocations. - const int valueCountGuestimate = 16; - const int lineLengthGuestimate = 256; - var values = new List(valueCountGuestimate); var builder = new StringBuilder(lineLengthGuestimate); while ((Header == null) && (!this.EOF)) @@ -1287,8 +1287,8 @@ internal void ReadHeader() _alreadyWarnedUnspecifiedName = alreadyWriteOutWarning; ReadHeader(); var prevalidated = false; - var values = new List(16); - var builder = new StringBuilder(256); + var values = new List(valueCountGuestimate); + var builder = new StringBuilder(lineLengthGuestimate); while (true) { ParseNextRecord(values, builder); From 5456685ce793fa8e89958bce2556f8ebfda67ff5 Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Mon, 6 Aug 2018 12:40:51 +0200 Subject: [PATCH 9/9] Casing of constants --- .../commands/utility/CSVCommands.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index 42671cfc6e1..12a1fa15a4f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1152,8 +1152,8 @@ internal class ImportCsvHelper // Initial sizes of the value list and the line stringbuilder. // Set to reasonable initial sizes. They may grow beyond these, // but this will prevent a few reallocations. - private const int valueCountGuestimate = 16; - private const int lineLengthGuestimate = 256; + private const int ValueCountGuestimate = 16; + private const int LineLengthGuestimate = 256; internal ImportCsvHelper(PSCmdlet cmdlet, char delimiter, IList header, string typeName, StreamReader streamReader) { @@ -1241,8 +1241,8 @@ internal void ReadHeader() TypeName = ReadTypeInformation(); } - var values = new List(valueCountGuestimate); - var builder = new StringBuilder(lineLengthGuestimate); + var values = new List(ValueCountGuestimate); + var builder = new StringBuilder(LineLengthGuestimate); while ((Header == null) && (!this.EOF)) { ParseNextRecord(values, builder); @@ -1287,8 +1287,8 @@ internal void ReadHeader() _alreadyWarnedUnspecifiedName = alreadyWriteOutWarning; ReadHeader(); var prevalidated = false; - var values = new List(valueCountGuestimate); - var builder = new StringBuilder(lineLengthGuestimate); + var values = new List(ValueCountGuestimate); + var builder = new StringBuilder(LineLengthGuestimate); while (true) { ParseNextRecord(values, builder);