You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2021/07/24 19:02:42 UTC

[lucenenet] branch master updated: PERFORMANCE: SWEEP: Replaced Substring method where appropriate with the overloads of number class Parse/TryParse that accept startIndex and length

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git


The following commit(s) were added to refs/heads/master by this push:
     new c73ffd1  PERFORMANCE: SWEEP: Replaced Substring method where appropriate with the overloads of number class Parse/TryParse that accept startIndex and length
c73ffd1 is described below

commit c73ffd12b4361594a0cb8067f5a91b04f465d87e
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sat Jul 10 18:25:18 2021 +0700

    PERFORMANCE: SWEEP: Replaced Substring method where appropriate with the overloads of number class Parse/TryParse that accept startIndex and length
---
 .../Analysis/CharFilter/HTMLStripCharFilter.cs     | 55 ++++++++++-------
 .../CharFilter/MappingCharFilterFactory.cs         |  7 ++-
 .../Analysis/Hunspell/Dictionary.cs                | 15 ++---
 .../Miscellaneous/WordDelimiterFilterFactory.cs    |  6 +-
 .../Egothor.Stemmer/DiffIt.cs                      |  4 +-
 .../Highlight/GradientFormatter.cs                 | 72 ++++++++++++++--------
 src/Lucene.Net/Index/CheckIndex.cs                 |  4 +-
 .../Index/PersistentSnapshotDeletionPolicy.cs      |  4 +-
 src/Lucene.Net/Util/Automaton/RegExp.cs            |  7 ++-
 9 files changed, 109 insertions(+), 65 deletions(-)

diff --git a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/HTMLStripCharFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/HTMLStripCharFilter.cs
index e70a392..c1ddaac 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/HTMLStripCharFilter.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/HTMLStripCharFilter.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
+using Integer = J2N.Numerics.Int32;
 
 namespace Lucene.Net.Analysis.CharFilters
 {
@@ -31885,17 +31886,19 @@ namespace Lucene.Net.Analysis.CharFilters
                             outputSegment.Clear();
                             string surrogatePair = YyText();
                             char highSurrogate = '\u0000';
-                            try
+                            // LUCENENET: Optimized parse so we don't allocate a substring.
+                            if (Integer.TryParse(surrogatePair, 2, 6 - 2, 16, out int highSurrogateInt32))
                             {
-                                highSurrogate = (char)int.Parse(surrogatePair.Substring(2, 6 - 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+                                highSurrogate = (char)highSurrogateInt32;
                             }
-                            catch (Exception e) when (e.IsException())
-                            { // should never happen
+                            else // should never happen
+                            {
                                 if (Debugging.AssertsEnabled) Debugging.Assert(false, "Exception parsing high surrogate '{0}'", surrogatePair.Substring(2, 6 - 2));
                             }
                             try
                             {
-                                outputSegment.UnsafeWrite((char)int.Parse(surrogatePair.Substring(10, 14 - 10), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
+                                // LUCENENET: Optimized parse so we don't allocate a substring
+                                outputSegment.UnsafeWrite((char)Integer.Parse(surrogatePair, 10, 14 - 10, 16));
                             }
                             catch (Exception e) when (e.IsException())
                             { // should never happen
@@ -31916,17 +31919,19 @@ namespace Lucene.Net.Analysis.CharFilters
                             string surrogatePair = YyText();
                             char highSurrogate = '\u0000';
                             char lowSurrogate = '\u0000';
-                            try
+                            // LUCENENET: Optimized parse so we don't allocate a substring.
+                            if (Integer.TryParse(surrogatePair, 2, 6 - 2, 16, out int highSurrogateInt32))
                             {
-                                highSurrogate = (char)int.Parse(surrogatePair.Substring(2, 6 - 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+                                highSurrogate = (char)highSurrogateInt32;
                             }
-                            catch (Exception e) when (e.IsException())
-                            { // should never happen
+                            else // should never happen
+                            {
                                 if (Debugging.AssertsEnabled) Debugging.Assert(false, "Exception parsing high surrogate '{0}'", surrogatePair.Substring(2, 6 - 2));
                             }
                             try
                             { // Low surrogates are in decimal range [56320, 57343]
-                                lowSurrogate = (char)int.Parse(surrogatePair.Substring(9, 14 - 9), CultureInfo.InvariantCulture);
+                                // LUCENENET: Optimized parse so we don't allocate a substring
+                                lowSurrogate = (char)Integer.Parse(surrogatePair, 9, 14 - 9, 10);
                             }
                             catch (Exception e) when (e.IsException())
                             { // should never happen
@@ -31955,12 +31960,13 @@ namespace Lucene.Net.Analysis.CharFilters
                         { // Handle paired UTF-16 surrogates.
                             string surrogatePair = YyText();
                             char highSurrogate = '\u0000';
-                            try
+                            // LUCENENET: Optimized parse so we don't allocate a substring.
+                            if (Integer.TryParse(surrogatePair, 1, 6 - 1, 10, out int highSurrogateInt32))
                             { // High surrogates are in decimal range [55296, 56319]
-                                highSurrogate = (char)int.Parse(surrogatePair.Substring(1, 6 - 1), CultureInfo.InvariantCulture);
+                                highSurrogate = (char)highSurrogateInt32;
                             }
-                            catch (Exception e) when (e.IsException())
-                            { // should never happen
+                            else // should never happen
+                            {
                                 if (Debugging.AssertsEnabled) Debugging.Assert(false, "Exception parsing high surrogate '{0}'", surrogatePair.Substring(1, 6 - 1));
                             }
                             if (char.IsHighSurrogate(highSurrogate))
@@ -31969,7 +31975,8 @@ namespace Lucene.Net.Analysis.CharFilters
                                 outputSegment.Clear();
                                 try
                                 {
-                                    outputSegment.UnsafeWrite((char)int.Parse(surrogatePair.Substring(10, 14 - 10), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
+                                    // LUCENENET: Optimized parse so we don't allocate a substring.
+                                    outputSegment.UnsafeWrite((char)Integer.Parse(surrogatePair, 10, 14 - 10, 16));
                                 }
                                 catch (Exception e) when (e.IsException())
                                 { // should never happen
@@ -31993,23 +32000,25 @@ namespace Lucene.Net.Analysis.CharFilters
                         { // Handle paired UTF-16 surrogates.
                             string surrogatePair = YyText();
                             char highSurrogate = '\u0000';
-                            try
+                            // LUCENENET: Optimized parse so we don't allocate a substring.
+                            if (Integer.TryParse(surrogatePair, 1, 6 - 1, 10, out int highSurrogateInt32))
                             { // High surrogates are in decimal range [55296, 56319]
-                                highSurrogate = (char)int.Parse(surrogatePair.Substring(1, 6 - 1), CultureInfo.InvariantCulture);
+                                highSurrogate = (char)highSurrogateInt32;
                             }
-                            catch (Exception e) when (e.IsException())
-                            { // should never happen
+                            else // should never happen
+                            {
                                 if (Debugging.AssertsEnabled) Debugging.Assert(false, "Exception parsing high surrogate '{0}'", surrogatePair.Substring(1, 6 - 1));
                             }
                             if (char.IsHighSurrogate(highSurrogate))
                             {
                                 char lowSurrogate = '\u0000';
-                                try
+                                // LUCENENET: Optimized parse so we don't allocate a substring.
+                                if (Integer.TryParse(surrogatePair, 9, 14 - 9, 10, out int lowSurrogateInt32))
                                 { // Low surrogates are in decimal range [56320, 57343]
-                                    lowSurrogate = (char)int.Parse(surrogatePair.Substring(9, 14 - 9), CultureInfo.InvariantCulture);
+                                    lowSurrogate = (char)lowSurrogateInt32;
                                 }
-                                catch (Exception e) when (e.IsException())
-                                { // should never happen
+                                else // should never happen
+                                {
                                     if (Debugging.AssertsEnabled) Debugging.Assert(false, "Exception parsing low surrogate '{0}'", surrogatePair.Substring(9, 14 - 9));
                                 }
                                 if (char.IsLowSurrogate(lowSurrogate))
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilterFactory.cs
index 37e549c..b6eb98d 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilterFactory.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilterFactory.cs
@@ -1,10 +1,11 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
 using Lucene.Net.Analysis.Util;
 using Lucene.Net.Util;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Text.RegularExpressions;
+using Integer = J2N.Numerics.Int32;
 
 namespace Lucene.Net.Analysis.CharFilters
 {
@@ -154,8 +155,8 @@ namespace Lucene.Net.Analysis.CharFilters
                             {
                                 throw new ArgumentException("Invalid escaped char in [" + s + "]");
                             }
-                            //c = (char)int.Parse(s.Substring(readPos, 4), 16);
-                            c = (char)int.Parse(s.Substring(readPos, 4), System.Globalization.NumberStyles.HexNumber);
+                            // LUCENENET: Optimized parse so we don't allocate a substring.
+                            c = (char)Integer.Parse(s, readPos, 4, 16);
                             readPos += 4;
                             break;
                     }
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
index bb13c63..7fc13e7 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
@@ -17,6 +17,7 @@ using System.IO;
 using System.Text;
 using System.Text.RegularExpressions;
 using JCG = J2N.Collections.Generic;
+using Integer = J2N.Numerics.Int32;
 
 namespace Lucene.Net.Analysis.Hunspell
 {
@@ -402,7 +403,7 @@ namespace Lucene.Net.Analysis.Hunspell
                     {
                         throw new ParseException(string.Format("Illegal {0} declaration", type), lineNumber);
                     }
-                    int num = int.Parse(parts[1], CultureInfo.InvariantCulture);
+                    int num = Integer.Parse(parts[1], radix: 10); // LUCENENET: specify radix 10 to make this culture invariant
                     FST<CharsRef> res = ParseConversions(reader, num, lineNumber); // LUCENENET: Pass linenumber so we can throw it
                     if (type.Equals("ICONV", StringComparison.Ordinal))
                     {
@@ -518,7 +519,7 @@ namespace Lucene.Net.Analysis.Hunspell
             bool crossProduct = args[2].Equals("Y", StringComparison.Ordinal);
             bool isSuffix = conditionPattern == SUFFIX_CONDITION_REGEX_PATTERN;
 
-            int numLines = int.Parse(args[3], CultureInfo.InvariantCulture);
+            int numLines = Integer.Parse(args[3], radix: 10); // LUCENENET: specify radix 10 to make this culture invariant
             affixData = ArrayUtil.Grow(affixData, (currentAffix << 3) + (numLines << 3));
             ByteArrayDataOutput affixWriter = new ByteArrayDataOutput(affixData, currentAffix << 3, numLines << 3);
 
@@ -549,7 +550,7 @@ namespace Lucene.Net.Analysis.Hunspell
 
                     if (aliasCount > 0)
                     {
-                        flagPart = GetAliasValue(int.Parse(flagPart, CultureInfo.InvariantCulture));
+                        flagPart = GetAliasValue(Integer.Parse(flagPart, radix: 10)); // LUCENENET: specify radix 10 to make this culture invariant
                     }
 
                     appendFlags = flagParsingStrategy.ParseFlags(flagPart);
@@ -1063,7 +1064,7 @@ namespace Lucene.Net.Analysis.Hunspell
                         string flagPart = line2.Substring(flagSep + 1, end - (flagSep + 1));
                         if (aliasCount > 0)
                         {
-                            flagPart = GetAliasValue(int.Parse(flagPart, CultureInfo.InvariantCulture));
+                            flagPart = GetAliasValue(Integer.Parse(flagPart, radix: 10)); // LUCENENET: specify radix 10 to make this culture invariant
                         }
 
                         wordForm = flagParsingStrategy.ParseFlags(flagPart);
@@ -1180,7 +1181,7 @@ namespace Lucene.Net.Analysis.Hunspell
             if (aliases == null)
             {
                 //first line should be the aliases count
-                int count = int.Parse(ruleArgs[1], CultureInfo.InvariantCulture);
+                int count = Integer.Parse(ruleArgs[1], radix: 10); // LUCENENET: specify radix 10 to make this culture invariant
                 aliases = new string[count];
             }
             else
@@ -1213,7 +1214,7 @@ namespace Lucene.Net.Analysis.Hunspell
             if (morphAliases == null)
             {
                 //first line should be the aliases count
-                int count = int.Parse(line.Substring(3), CultureInfo.InvariantCulture);
+                int count = Integer.Parse(line.Substring(3), radix: 10); // LUCENENET: specify radix 10 to make this culture invariant
                 morphAliases = new string[count];
             }
             else
@@ -1312,7 +1313,7 @@ namespace Lucene.Net.Analysis.Hunspell
                     {
                         continue;
                     }
-                    flags[upto++] = (char)int.Parse(replacement, CultureInfo.InvariantCulture);
+                    flags[upto++] = (char)Integer.Parse(replacement, radix: 10); // LUCENENET: specify radix 10 to make this culture invariant
                 }
 
                 if (upto < flags.Length)
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Miscellaneous/WordDelimiterFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Miscellaneous/WordDelimiterFilterFactory.cs
index eb4b691..8ce8c14 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Miscellaneous/WordDelimiterFilterFactory.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Miscellaneous/WordDelimiterFilterFactory.cs
@@ -1,4 +1,4 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
 using Lucene.Net.Analysis.Util;
 using Lucene.Net.Util;
 using System;
@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
 using System.Text.RegularExpressions;
+using Integer = J2N.Numerics.Int32;
 using JCG = J2N.Collections.Generic;
 
 namespace Lucene.Net.Analysis.Miscellaneous
@@ -254,7 +255,8 @@ namespace Lucene.Net.Analysis.Miscellaneous
                             {
                                 throw new ArgumentException("Invalid escaped char in [" + s + "]");
                             }
-                            c = (char)int.Parse(s.Substring(readPos, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+                            // LUCENENET: Optimized parse so we don't allocate a substring
+                            c = (char)Integer.Parse(s, readPos, 4, radix: 16);
                             readPos += 4;
                             break;
                     }
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/DiffIt.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/DiffIt.cs
index eff973d..b6ecc42 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/DiffIt.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/DiffIt.cs
@@ -6,6 +6,7 @@ using System.Globalization;
 using System.IO;
 using System.Text;
 using Console = Lucene.Net.Util.SystemConsole;
+using Integer = J2N.Numerics.Int32;
 
 /*
                     Egothor Software License version 1.00
@@ -72,7 +73,8 @@ namespace Egothor.Stemmer
     {
         internal static int Get(int i, string s)
         {
-            if (!int.TryParse(s.Substring(i, 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out int result))
+            // LUCENENET: Optimized so we don't alocate a substring
+            if (!Integer.TryParse(s, i, 1, radix: 10, out int result))
             {
                 return 1;
             }
diff --git a/src/Lucene.Net.Highlighter/Highlight/GradientFormatter.cs b/src/Lucene.Net.Highlighter/Highlight/GradientFormatter.cs
index ba8e60b..085e88a 100644
--- a/src/Lucene.Net.Highlighter/Highlight/GradientFormatter.cs
+++ b/src/Lucene.Net.Highlighter/Highlight/GradientFormatter.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Text;
+using Integer = J2N.Numerics.Int32;
 
 namespace Lucene.Net.Search.Highlight
 {
@@ -73,13 +74,13 @@ namespace Lucene.Net.Search.Highlight
                     throw new ArgumentException("minForegroundColor is not 7 bytes long eg a hex " 
                         + "RGB value such as #FFFFFF");
                 }
-                m_fgRMin = HexToInt32(minForegroundColor.Substring(1, 3 - 1));
-                m_fgGMin = HexToInt32(minForegroundColor.Substring(3, 5 - 3));
-                m_fgBMin = HexToInt32(minForegroundColor.Substring(5, 7 - 5));
+                m_fgRMin = HexToInt32(minForegroundColor, 1, 3 - 1);
+                m_fgGMin = HexToInt32(minForegroundColor, 3, 5 - 3);
+                m_fgBMin = HexToInt32(minForegroundColor, 5, 7 - 5);
 
-                m_fgRMax = HexToInt32(maxForegroundColor.Substring(1, 3 - 1));
-                m_fgGMax = HexToInt32(maxForegroundColor.Substring(3, 5 - 3));
-                m_fgBMax = HexToInt32(maxForegroundColor.Substring(5, 7 - 5));
+                m_fgRMax = HexToInt32(maxForegroundColor, 1, 3 - 1);
+                m_fgGMax = HexToInt32(maxForegroundColor, 3, 5 - 3);
+                m_fgBMax = HexToInt32(maxForegroundColor, 5, 7 - 5);
             }
 
             m_highlightBackground = (minBackgroundColor != null) 
@@ -96,13 +97,13 @@ namespace Lucene.Net.Search.Highlight
                     throw new ArgumentException("minBackgroundColor is not 7 bytes long eg a hex " 
                         + "RGB value such as #FFFFFF");
                 }
-                m_bgRMin = HexToInt32(minBackgroundColor.Substring(1, 3 - 1));
-                m_bgGMin = HexToInt32(minBackgroundColor.Substring(3, 5 - 3));
-                m_bgBMin = HexToInt32(minBackgroundColor.Substring(5, 7 - 5));
+                m_bgRMin = HexToInt32(minBackgroundColor, 1, 3 - 1);
+                m_bgGMin = HexToInt32(minBackgroundColor, 3, 5 - 3);
+                m_bgBMin = HexToInt32(minBackgroundColor, 5, 7 - 5);
 
-                m_bgRMax = HexToInt32(maxBackgroundColor.Substring(1, 3 - 1));
-                m_bgGMax = HexToInt32(maxBackgroundColor.Substring(3, 5 - 3));
-                m_bgBMax = HexToInt32(maxBackgroundColor.Substring(5, 7 - 5));
+                m_bgRMax = HexToInt32(maxBackgroundColor, 1, 3 - 1);
+                m_bgGMax = HexToInt32(maxBackgroundColor, 3, 5 - 3);
+                m_bgBMax = HexToInt32(maxBackgroundColor, 5, 7 - 5);
             }
             //        this.corpusReader = corpusReader;
             this.maxScore = maxScore;
@@ -202,23 +203,44 @@ namespace Lucene.Net.Search.Highlight
         /// character is not in the set [0-9a-fA-f]</exception>
         public static int HexToInt32(string hex)
         {
-            int len = hex.Length;
-            if (len > 16)
-                throw NumberFormatException.Create();
-
-            try
+            if ((hex.Length > 16) || !Integer.TryParse(hex, radix: 16, out int result))
             {
-                // LUCENENET NOTE: Convert.ToInt32(string, int) throws a
-                // FormatException if the character does not fall in
-                // the correct range, which is the behavior we are expecting.
-                // But throws an ArgumentException if passed a negative number.
-                // So we need to convert to FormatException to provide the correct behavior.
-                return Convert.ToInt32(hex, 16);
+                throw NumberFormatException.Create();
             }
-            catch (ArgumentException e)
+
+            return result;
+        }
+
+        /// <summary> 
+        /// Converts a hex string at the specified index and length of <paramref name="hex"/>
+        /// into an <see cref="int"/>.
+        /// <para/>
+        /// NOTE: This was hexToInt() in Lucene
+        /// </summary>
+        /// <param name="hex">
+        /// A string in capital or lower case hex, of no more then 16
+        /// characters.
+        /// </param>
+        /// <param name="startIndex">The index of the first character to begin parsing.</param>
+        /// <param name="length">The number of characters to parse.</param>
+        /// <exception cref="FormatException">if the string is more than 16 characters long, or if any
+        /// character is not in the set [0-9a-fA-f]</exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        /// <paramref name="startIndex"/> or <paramref name="length"/> is less than zero.
+        /// <para/>
+        /// -or-
+        /// <para/>
+        /// <paramref name="startIndex"/> and <paramref name="length"/> refer to a location outside of <paramref name="hex"/>.
+        /// </exception>
+        // LUCENENET specific overload
+        public static int HexToInt32(string hex, int startIndex, int length)
+        {
+            if ((length > 16) || !Integer.TryParse(hex, startIndex, length, radix: 16, out int result))
             {
-                throw NumberFormatException.Create(e);
+                throw NumberFormatException.Create();
             }
+
+            return result;
         }
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/CheckIndex.cs b/src/Lucene.Net/Index/CheckIndex.cs
index c8b85f3..191b5b8 100644
--- a/src/Lucene.Net/Index/CheckIndex.cs
+++ b/src/Lucene.Net/Index/CheckIndex.cs
@@ -11,6 +11,7 @@ using System.Globalization;
 using System.IO;
 using System.Threading;
 using Console = Lucene.Net.Util.SystemConsole;
+using Integer = J2N.Numerics.Int32;
 
 namespace Lucene.Net.Index
 {
@@ -676,7 +677,8 @@ namespace Lucene.Net.Index
                 int segmentName = 0;
                 try
                 {
-                    segmentName = int.Parse(info.Info.Name.Substring(1), CultureInfo.InvariantCulture);
+                    // LUCENENET: Optimized to not allocate a substring during the parse
+                    segmentName = Integer.Parse(info.Info.Name, 1, info.Info.Name.Length - 1, radix: 10);
                 }
                 catch
                 {
diff --git a/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs b/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
index 88a1e2c..f9bcdb9 100644
--- a/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net/Index/PersistentSnapshotDeletionPolicy.cs
@@ -5,6 +5,7 @@ using System.Globalization;
 using System.IO;
 using System.Runtime.CompilerServices;
 using System.Runtime.ExceptionServices;
+using Long = J2N.Numerics.Int64;
 
 namespace Lucene.Net.Index
 {
@@ -306,7 +307,8 @@ namespace Lucene.Net.Index
                 {
                     if (file.StartsWith(SNAPSHOTS_PREFIX, StringComparison.Ordinal))
                     {
-                        long gen = Convert.ToInt64(file.Substring(SNAPSHOTS_PREFIX.Length), CultureInfo.InvariantCulture);
+                        // LUCENENET: Optimized to not allocate a substring during the parse
+                        long gen = Long.Parse(file, SNAPSHOTS_PREFIX.Length, file.Length - SNAPSHOTS_PREFIX.Length, radix: 10);
                         if (genLoaded == -1 || gen > genLoaded)
                         {
                             snapshotFiles.Add(file);
diff --git a/src/Lucene.Net/Util/Automaton/RegExp.cs b/src/Lucene.Net/Util/Automaton/RegExp.cs
index 6022e06..dd78d20 100644
--- a/src/Lucene.Net/Util/Automaton/RegExp.cs
+++ b/src/Lucene.Net/Util/Automaton/RegExp.cs
@@ -6,6 +6,7 @@ using System.Globalization;
 using System.IO;
 using System.Runtime.CompilerServices;
 using System.Text;
+using Integer = J2N.Numerics.Int32;
 using JCG = J2N.Collections.Generic;
 
 /*
@@ -1121,7 +1122,8 @@ namespace Lucene.Net.Util.Automaton
                     {
                         throw new ArgumentException("integer expected at position " + pos);
                     }
-                    int n = Convert.ToInt32(b.Substring(start, pos - start), CultureInfo.InvariantCulture);
+                    // LUCENENET: Optimized so we don't allocate a substring during the parse
+                    int n = Integer.Parse(b, start, pos - start, radix: 10);
                     int m = -1;
                     if (Match(','))
                     {
@@ -1132,7 +1134,8 @@ namespace Lucene.Net.Util.Automaton
                         }
                         if (start != pos)
                         {
-                            m = Convert.ToInt32(b.Substring(start, pos - start), CultureInfo.InvariantCulture);
+                            // LUCENENET: Optimized so we don't allocate a substring during the parse
+                            m = Integer.Parse(b, start, pos - start, radix: 10);
                         }
                     }
                     else