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 2020/07/21 09:48:56 UTC

[lucenenet] 22/24: SWEEP: Consolidated empty array creation code

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

commit efdd98ccdcc32b6d2ced6ca4fa7bf87361dc0a3a
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sat Jul 18 15:38:38 2020 +0700

    SWEEP: Consolidated empty array creation code
---
 .../Analysis/Hunspell/Dictionary.cs                | 10 +--------
 .../Analysis/Query/QueryAutoStopWordAnalyzer.cs    | 12 ++---------
 .../Analysis/Shingle/ShingleFilter.cs              | 11 ++--------
 .../Tartarus/Snowball/Among.cs                     |  7 +------
 .../Tartarus/Snowball/SnowballProgram.cs           |  8 ++------
 src/Lucene.Net.Analysis.Kuromoji/Util/CSVUtil.cs   | 13 +++---------
 src/Lucene.Net.Benchmark/Support/TagSoup/Parser.cs | 11 ++--------
 .../BlockTerms/TermsIndexWriterBase.cs             | 15 +++-----------
 .../SimpleText/SimpleTextDocValuesReader.cs        | 13 +++---------
 src/Lucene.Net.Facet/FacetsConfig.cs               | 13 +++---------
 .../SortedSet/SortedSetDocValuesFacetCounts.cs     | 11 ++--------
 src/Lucene.Net.Grouping/GroupingSearch.cs          | 21 +------------------
 src/Lucene.Net.Queries/CustomScoreQuery.cs         | 22 +++-----------------
 src/Lucene.Net.Queries/TermsFilter.cs              | 10 +--------
 .../Suggest/Fst/FSTCompletionLookup.cs             | 11 ++--------
 .../Suggest/SortedInputIterator.cs                 | 11 ++--------
 .../Suggest/SortedTermFreqIteratorWrapper.cs       | 11 ++--------
 .../Index/BaseDocValuesFormatTestCase.cs           |  4 ++--
 .../Index/BaseIndexFileFormatTestCase.cs           |  9 --------
 src/Lucene.Net.Tests/Util/TestArrayUtil.cs         |  7 ++-----
 src/Lucene.Net/Codecs/BlockTreeTermsReader.cs      |  8 ++------
 src/Lucene.Net/Codecs/PostingsFormat.cs            |  8 ++------
 src/Lucene.Net/Document/Document.cs                |  8 ++------
 src/Lucene.Net/Index/Fields.cs                     |  8 ++------
 src/Lucene.Net/Index/IndexFileDeleter.cs           | 10 +--------
 src/Lucene.Net/Index/MultiTermsEnum.cs             |  7 +------
 src/Lucene.Net/Index/ParallelCompositeReader.cs    | 11 ++--------
 src/Lucene.Net/Index/ReaderSlice.cs                |  9 ++------
 src/Lucene.Net/Index/Terms.cs                      |  8 ++------
 src/Lucene.Net/Search/CachingCollector.cs          |  8 ++------
 src/Lucene.Net/Search/FieldComparator.cs           | 17 ++++-----------
 src/Lucene.Net/Search/TopDocs.cs                   | 10 +--------
 src/Lucene.Net/Search/TopFieldCollector.cs         |  8 ++------
 src/Lucene.Net/Search/TopScoreDocCollector.cs      | 13 +++---------
 src/Lucene.Net/Support/Arrays.cs                   | 24 ++++++++++++++++++++++
 .../Util/Automaton/DaciukMihovAutomatonBuilder.cs  | 15 +++-----------
 src/Lucene.Net/Util/Automaton/State.cs             | 12 ++---------
 src/Lucene.Net/Util/Bits.cs                        |  9 +++-----
 src/Lucene.Net/Util/BytesRef.cs                    |  8 ++------
 src/Lucene.Net/Util/CharsRef.cs                    |  9 +++-----
 src/Lucene.Net/Util/FieldCacheSanityChecker.cs     | 10 +--------
 src/Lucene.Net/Util/Fst/FST.cs                     |  8 ++------
 src/Lucene.Net/Util/IntsRef.cs                     |  7 +------
 src/Lucene.Net/Util/LongsRef.cs                    |  7 +------
 src/Lucene.Net/Util/PagedBytes.cs                  |  8 ++------
 src/Lucene.Net/Util/WAH8DocIdSet.cs                | 13 +++---------
 46 files changed, 114 insertions(+), 379 deletions(-)

diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
index 80b83f5..70bc9c5 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
@@ -1079,19 +1079,11 @@ namespace Lucene.Net.Analysis.Hunspell
         /// </summary>
         private class DoubleASCIIFlagParsingStrategy : FlagParsingStrategy
         {
-            // LUCENENET specific - optimized empty array creation
-            private static readonly char[] EMPTY_CHARS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<char>();
-#else
-                new char[0];
-#endif
-
             internal override char[] ParseFlags(string rawFlags)
             {
                 if (rawFlags.Length == 0)
                 {
-                    return EMPTY_CHARS; // LUCENENET: Optimized char[] creation
+                    return Arrays.Empty<char>(); ; // LUCENENET: Optimized char[] creation
                 }
 
                 StringBuilder builder = new StringBuilder();
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
index f31f195..243fa3b 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
@@ -1,8 +1,8 @@
 using Lucene.Net.Analysis.Core;
 using Lucene.Net.Analysis.Util;
 using Lucene.Net.Index;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
-using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -171,17 +171,9 @@ namespace Lucene.Net.Analysis.Query
         public string[] GetStopWords(string fieldName)
         {            
             var stopWords = stopWordsPerField[fieldName];
-            return stopWords != null ? stopWords.ToArray() : EMPTY_STRINGS;
+            return stopWords != null ? stopWords.ToArray() : Arrays.Empty<string>();
         }
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<string>();
-#else
-                new string[0];
-#endif
-
         /// <summary>
         /// Provides information on which stop words have been identified for all fields
         /// </summary>
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
index 147efe7..4c2a1e1 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Shingle/ShingleFilter.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Analysis.TokenAttributes;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
 using System;
 using System.Collections.Generic;
@@ -306,17 +307,9 @@ namespace Lucene.Net.Analysis.Shingle
         /// <param name="fillerToken"> string to insert at each position where there is no token </param>
         public void SetFillerToken(string fillerToken)
         {
-            this.fillerToken = null == fillerToken ? EMPTY_CHARS : fillerToken.ToCharArray();
+            this.fillerToken = null == fillerToken ? Arrays.Empty<char>() : fillerToken.ToCharArray();
         }
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly char[] EMPTY_CHARS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<char>();
-#else
-                new char[0];
-#endif
-
         public override bool IncrementToken()
         {
             bool tokenAvailable = false;
diff --git a/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/Among.cs b/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/Among.cs
index 1488daa..d636a2f 100644
--- a/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/Among.cs
+++ b/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/Among.cs
@@ -47,12 +47,7 @@ namespace Lucene.Net.Tartarus.Snowball
     /// </summary>
     public class Among
     {
-        private readonly Type[] EMPTY_PARAMS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Type>();
-#else
-            new Type[0];
-#endif
+        private readonly Type[] EMPTY_PARAMS = Arrays.Empty<Type>();
 
         public Among(string s, int substring_i, int result,
             string methodname, SnowballProgram methodobject)
diff --git a/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/SnowballProgram.cs b/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/SnowballProgram.cs
index f608592..04a60b2 100644
--- a/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/SnowballProgram.cs
+++ b/src/Lucene.Net.Analysis.Common/Tartarus/Snowball/SnowballProgram.cs
@@ -49,12 +49,8 @@ namespace Lucene.Net.Tartarus.Snowball
     /// </summary>
     public abstract class SnowballProgram
     {
-        private static readonly object[] EMPTY_ARGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<object>();
-#else
-            new object[0];
-#endif
+        private static readonly object[] EMPTY_ARGS = Arrays.Empty<object>();
+
         protected SnowballProgram()
         {
             m_current = new char[8];
diff --git a/src/Lucene.Net.Analysis.Kuromoji/Util/CSVUtil.cs b/src/Lucene.Net.Analysis.Kuromoji/Util/CSVUtil.cs
index d588ad5..f9e939c 100644
--- a/src/Lucene.Net.Analysis.Kuromoji/Util/CSVUtil.cs
+++ b/src/Lucene.Net.Analysis.Kuromoji/Util/CSVUtil.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support;
+using System;
 using System.Collections.Generic;
 using System.Text;
 using System.Text.RegularExpressions;
@@ -35,14 +36,6 @@ namespace Lucene.Net.Analysis.Ja.Util
 
         private const string ESCAPED_QUOTE = "\"\"";
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
-
         private CSVUtil() { } // no instance!!!
 
         /// <summary>
@@ -83,7 +76,7 @@ namespace Lucene.Net.Analysis.Ja.Util
             // Validate
             if (quoteCount % 2 != 0)
             {
-                return EMPTY_STRINGS;
+                return Arrays.Empty<string>();
             }
 
             return result.ToArray(/*new String[result.size()]*/);
diff --git a/src/Lucene.Net.Benchmark/Support/TagSoup/Parser.cs b/src/Lucene.Net.Benchmark/Support/TagSoup/Parser.cs
index 30931f0..2edb76e 100644
--- a/src/Lucene.Net.Benchmark/Support/TagSoup/Parser.cs
+++ b/src/Lucene.Net.Benchmark/Support/TagSoup/Parser.cs
@@ -15,6 +15,7 @@
 // The TagSoup parser
 
 using J2N.Text;
+using Lucene.Net.Support;
 using Sax;
 using Sax.Ext;
 using Sax.Helpers;
@@ -1082,14 +1083,6 @@ namespace TagSoup
             return value;
         }
 
-        // LUCENENET: Optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
-
         /// <summary>
         ///   Split the supplied string into words or phrases seperated by spaces.
         ///   Recognises quotes around a phrase and doesn't split it.
@@ -1101,7 +1094,7 @@ namespace TagSoup
             val = val.Trim();
             if (val.Length == 0)
             {
-                return EMPTY_STRINGS;
+                return Arrays.Empty<string>();
             }
             var l = new List<string>();
             int s = 0;
diff --git a/src/Lucene.Net.Codecs/BlockTerms/TermsIndexWriterBase.cs b/src/Lucene.Net.Codecs/BlockTerms/TermsIndexWriterBase.cs
index c579fde..4c57c72 100644
--- a/src/Lucene.Net.Codecs/BlockTerms/TermsIndexWriterBase.cs
+++ b/src/Lucene.Net.Codecs/BlockTerms/TermsIndexWriterBase.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Index;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
 using System;
 
@@ -31,20 +32,10 @@ namespace Lucene.Net.Codecs.BlockTerms
     public abstract class TermsIndexWriterBase : IDisposable
     {
         // LUCENENET specific - optimized empty array creation
-        internal static readonly short[] EMPTY_INT16S =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<short>();
-#else
-            new short[0];
-#endif
+        internal static readonly short[] EMPTY_INT16S = Arrays.Empty<short>();
 
         // LUCENENET specific - optimized empty array creation
-        internal static readonly int[] EMPTY_INT32S =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<int>();
-#else
-            new int[0];
-#endif
+        internal static readonly int[] EMPTY_INT32S = Arrays.Empty<int>();
 
         /// <summary>Terms index API for a single field.</summary>
         public abstract class FieldWriter
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
index a5a1086..586a5bb 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
@@ -1,4 +1,5 @@
 using J2N.Text;
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -495,18 +496,10 @@ namespace Lucene.Net.Codecs.SimpleText
                 _input = input;
                 _scratch = scratch;
                 _decoderFormat = field.Pattern;
-                _currentOrds = EMPTY_STRINGS;
+                _currentOrds = Arrays.Empty<string>();
                 _currentIndex = 0;
             }
 
-            // LUCENENET specific - optimized empty array creation
-            private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<string>();
-#else
-                new string[0];
-#endif
-
             private string[] _currentOrds;
             private int _currentIndex;
 
@@ -527,7 +520,7 @@ namespace Lucene.Net.Codecs.SimpleText
                                 docID * (1 + _field.OrdPattern.Length));
                     SimpleTextUtil.ReadLine(_input, _scratch);
                     var ordList = _scratch.Utf8ToString().Trim();
-                    _currentOrds = ordList.Length == 0 ? EMPTY_STRINGS : ordList.Split(',').TrimEnd();
+                    _currentOrds = ordList.Length == 0 ? Arrays.Empty<string>() : ordList.Split(',').TrimEnd();
                     _currentIndex = 0;
                 }
                 catch (IOException ioe)
diff --git a/src/Lucene.Net.Facet/FacetsConfig.cs b/src/Lucene.Net.Facet/FacetsConfig.cs
index 42b293f..300614a 100644
--- a/src/Lucene.Net.Facet/FacetsConfig.cs
+++ b/src/Lucene.Net.Facet/FacetsConfig.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support;
+using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -602,14 +603,6 @@ namespace Lucene.Net.Facet
         // Escapes any occurrence of the path component inside the label:
         private const char ESCAPE_CHAR = '\u001E';
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
-
         /// <summary>
         /// Turns a dim + path into an encoded string.
         /// </summary>
@@ -675,7 +668,7 @@ namespace Lucene.Net.Facet
             int length = s.Length;
             if (length == 0)
             {
-                return EMPTY_STRINGS;
+                return Arrays.Empty<string>();
             }
             char[] buffer = new char[length];
 
diff --git a/src/Lucene.Net.Facet/SortedSet/SortedSetDocValuesFacetCounts.cs b/src/Lucene.Net.Facet/SortedSet/SortedSetDocValuesFacetCounts.cs
index 1a6e61f..23c32cd 100644
--- a/src/Lucene.Net.Facet/SortedSet/SortedSetDocValuesFacetCounts.cs
+++ b/src/Lucene.Net.Facet/SortedSet/SortedSetDocValuesFacetCounts.cs
@@ -1,4 +1,5 @@
 using J2N.Text;
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 
@@ -57,14 +58,6 @@ namespace Lucene.Net.Facet.SortedSet
         internal readonly string field;
         internal readonly int[] counts;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
-
         /// <summary>
         /// Sparse faceting: returns any dimension that had any
         /// hits, topCount labels per dimension. 
@@ -153,7 +146,7 @@ namespace Lucene.Net.Facet.SortedSet
                 labelValues[i] = new LabelAndValue(parts[1], ordAndValue.Value);
             }
 
-            return new FacetResult(dim, EMPTY_STRINGS, dimCount, labelValues, childCount);
+            return new FacetResult(dim, Arrays.Empty<string>(), dimCount, labelValues, childCount);
         }
 
         /// <summary>
diff --git a/src/Lucene.Net.Grouping/GroupingSearch.cs b/src/Lucene.Net.Grouping/GroupingSearch.cs
index b391f74..f056796 100644
--- a/src/Lucene.Net.Grouping/GroupingSearch.cs
+++ b/src/Lucene.Net.Grouping/GroupingSearch.cs
@@ -58,25 +58,6 @@ namespace Lucene.Net.Search.Grouping
         private ICollection /* Collection<?> */ matchingGroups;
         private IBits matchingGroupHeads;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly SortField[] EMPTY_SORTFIELDS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<SortField>();
-#else
-            new SortField[0];
-#endif
-
-        // LUCENENET specific - optimized empty array creation
-        private class EmptyGroupDocsHolder<TGroupValue>
-        {
-            public static readonly GroupDocs<TGroupValue>[] EMPTY_GROUPDOCS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<GroupDocs<TGroupValue>>();
-#else
-                new GroupDocs<TGroupValue>[0];
-#endif
-        }
-
         /// <summary>
         /// Constructs a <see cref="GroupingSearch"/> instance that groups documents by index terms using the <see cref="FieldCache"/>.
         /// The group field can only have one token per document. This means that the field must not be analysed.
@@ -310,7 +291,7 @@ namespace Lucene.Net.Search.Grouping
             if (topSearchGroups == null)
             {
                 // LUCENENET specific - optimized empty array creation
-                return new TopGroups<TGroupValue>(EMPTY_SORTFIELDS, EMPTY_SORTFIELDS, 0, 0, EmptyGroupDocsHolder<TGroupValue>.EMPTY_GROUPDOCS, float.NaN);
+                return new TopGroups<TGroupValue>(Arrays.Empty<SortField>(), Arrays.Empty<SortField>(), 0, 0, Arrays.Empty<GroupDocs<TGroupValue>>(), float.NaN);
             }
 
             int topNInsideGroup = groupDocsOffset + groupDocsLimit;
diff --git a/src/Lucene.Net.Queries/CustomScoreQuery.cs b/src/Lucene.Net.Queries/CustomScoreQuery.cs
index 1d78a75..33beedf 100644
--- a/src/Lucene.Net.Queries/CustomScoreQuery.cs
+++ b/src/Lucene.Net.Queries/CustomScoreQuery.cs
@@ -43,27 +43,11 @@ namespace Lucene.Net.Queries
         private Query[] scoringQueries; // never null (empty array if there are no valSrcQueries).
         private bool strict = false; // if true, valueSource part of query does not take part in weights normalization.
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly FunctionQuery[] EMPTY_FUNCTION_QUERIES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<FunctionQuery>();
-#else
-            new FunctionQuery[0];
-#endif
-
-        // LUCENENET specific - optimized empty array creation
-        private static readonly Query[] EMPTY_QUERIES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Query>();
-#else
-            new Query[0];
-#endif
-
         /// <summary>
         /// Create a <see cref="CustomScoreQuery"/> over input <paramref name="subQuery"/>. </summary>
         /// <param name="subQuery"> the sub query whose scored is being customized. Must not be <c>null</c>.  </param>
         public CustomScoreQuery(Query subQuery)
-            : this(subQuery, EMPTY_FUNCTION_QUERIES)
+            : this(subQuery, Arrays.Empty<FunctionQuery>())
         {
         }
 
@@ -73,7 +57,7 @@ namespace Lucene.Net.Queries
         /// <param name="scoringQuery"> a value source query whose scores are used in the custom score
         /// computation.  This parameter is optional - it can be null. </param>
         public CustomScoreQuery(Query subQuery, FunctionQuery scoringQuery)
-            : this(subQuery, scoringQuery != null ? new FunctionQuery[] { scoringQuery } : EMPTY_FUNCTION_QUERIES)
+            : this(subQuery, scoringQuery != null ? new FunctionQuery[] { scoringQuery } : Arrays.Empty<FunctionQuery>())
         // don't want an array that contains a single null..
         {
         }
@@ -86,7 +70,7 @@ namespace Lucene.Net.Queries
         public CustomScoreQuery(Query subQuery, params FunctionQuery[] scoringQueries)
         {
             this.subQuery = subQuery;
-            this.scoringQueries = scoringQueries != null ? scoringQueries : EMPTY_QUERIES;
+            this.scoringQueries = scoringQueries ?? Arrays.Empty<Query>();
             if (subQuery == null)
             {
                 throw new ArgumentException("<subquery> must not be null!");
diff --git a/src/Lucene.Net.Queries/TermsFilter.cs b/src/Lucene.Net.Queries/TermsFilter.cs
index 1eb1df4..eb13386 100644
--- a/src/Lucene.Net.Queries/TermsFilter.cs
+++ b/src/Lucene.Net.Queries/TermsFilter.cs
@@ -50,14 +50,6 @@ namespace Lucene.Net.Queries
         private readonly int hashCode; // cached hashcode for fast cache lookups
         private const int PRIME = 31;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
         /// <summary>
         /// Creates a new <see cref="TermsFilter"/> from the given list. The list
         /// can contain duplicate terms and multiple fields.
@@ -168,7 +160,7 @@ namespace Lucene.Net.Queries
             // an automaton an call intersect on the termsenum if the density is high
             
             int hash = 9;
-            var serializedTerms = EMPTY_BYTES;
+            var serializedTerms = Arrays.Empty<byte>();
             this.offsets = new int[length + 1];
             int lastEndOffset = 0;
             int index = 0;
diff --git a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
index b89c2da..bfe7257 100644
--- a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
+++ b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletionLookup.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Store;
+using Lucene.Net.Support;
 using Lucene.Net.Support.IO;
 using Lucene.Net.Util;
 using Lucene.Net.Util.Fst;
@@ -90,14 +91,6 @@ namespace Lucene.Net.Search.Suggest.Fst
         /// Number of entries the lookup was built with </summary>
         private long count = 0;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
 
         /// <summary>
         /// This constructor prepares for creating a suggested FST using the
@@ -167,7 +160,7 @@ namespace Lucene.Net.Search.Suggest.Fst
             count = 0;
             try
             {
-                byte[] buffer = EMPTY_BYTES;
+                byte[] buffer = Arrays.Empty<byte>();
                 ByteArrayDataOutput output = new ByteArrayDataOutput(buffer);
                 BytesRef spare;
                 while ((spare = iterator.Next()) != null)
diff --git a/src/Lucene.Net.Suggest/Suggest/SortedInputIterator.cs b/src/Lucene.Net.Suggest/Suggest/SortedInputIterator.cs
index 38be770..daed7fc 100644
--- a/src/Lucene.Net.Suggest/Suggest/SortedInputIterator.cs
+++ b/src/Lucene.Net.Suggest/Suggest/SortedInputIterator.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Store;
+using Lucene.Net.Support;
 using Lucene.Net.Support.IO;
 using Lucene.Net.Util;
 using System;
@@ -47,14 +48,6 @@ namespace Lucene.Net.Search.Suggest
         private BytesRef payload = new BytesRef();
         private ISet<BytesRef> contexts = null;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
         /// <summary>
         /// Creates a new sorted wrapper, using <see cref="BytesRef.UTF8SortedAsUnicodeComparer"/>
         /// for sorting. 
@@ -199,7 +192,7 @@ namespace Lucene.Net.Search.Suggest
             try
             {
                 BytesRef spare;
-                byte[] buffer = EMPTY_BYTES;
+                byte[] buffer = Arrays.Empty<byte>();
                 var output = new ByteArrayDataOutput(buffer);
 
                 while ((spare = source.Next()) != null)
diff --git a/src/Lucene.Net.Suggest/Suggest/SortedTermFreqIteratorWrapper.cs b/src/Lucene.Net.Suggest/Suggest/SortedTermFreqIteratorWrapper.cs
index 5a82421..6ae4fa9 100644
--- a/src/Lucene.Net.Suggest/Suggest/SortedTermFreqIteratorWrapper.cs
+++ b/src/Lucene.Net.Suggest/Suggest/SortedTermFreqIteratorWrapper.cs
@@ -1,5 +1,6 @@
 using Lucene.Net.Search.Spell;
 using Lucene.Net.Store;
+using Lucene.Net.Support;
 using Lucene.Net.Support.IO;
 using Lucene.Net.Util;
 using System;
@@ -42,14 +43,6 @@ namespace Lucene.Net.Search.Suggest
         private long weight;
         private readonly BytesRef scratch = new BytesRef();
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
         /// <summary>
         /// Creates a new sorted wrapper, using <see cref="BytesRef.UTF8SortedAsUnicodeComparer"/>
         /// for sorting. 
@@ -144,7 +137,7 @@ namespace Lucene.Net.Search.Suggest
             try
             {
                 BytesRef spare;
-                byte[] buffer = EMPTY_BYTES;
+                byte[] buffer = Arrays.Empty<byte>();
                 ByteArrayDataOutput output = new ByteArrayDataOutput(buffer);
 
                 while ((spare = source.Next()) != null)
diff --git a/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
index e63c350..5dec185 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseDocValuesFormatTestCase.cs
@@ -3496,7 +3496,7 @@ namespace Lucene.Net.Index
                 {
                     Document doc = new Document();
                     Field idField = new StringField("id", "", Field.Store.NO);
-                    Field storedBinField = new StoredField("storedBin", EMPTY_BYTES);
+                    Field storedBinField = new StoredField("storedBin", Arrays.Empty<byte>());
                     Field dvBinField = new BinaryDocValuesField("dvBin", new BytesRef());
                     Field dvSortedField = new SortedDocValuesField("dvSorted", new BytesRef());
                     Field storedNumericField = new StoredField("storedNum", "");
@@ -3621,7 +3621,7 @@ namespace Lucene.Net.Index
                 using (RandomIndexWriter writer = new RandomIndexWriter(Random, dir, conf))
                 {
                     Field idField = new StringField("id", "", Field.Store.NO);
-                    Field storedBinField = new StoredField("storedBin", EMPTY_BYTES);
+                    Field storedBinField = new StoredField("storedBin", Arrays.Empty<byte>());
                     Field dvBinField = new BinaryDocValuesField("dvBin", new BytesRef());
                     Field dvSortedField = new SortedDocValuesField("dvSorted", new BytesRef());
                     Field storedNumericField = new StoredField("storedNum", "");
diff --git a/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
index 2fecb22..a04c134 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
@@ -5,7 +5,6 @@ using Lucene.Net.Index.Extensions;
 using Lucene.Net.Store;
 using Lucene.Net.TestFramework;
 using Lucene.Net.Util;
-using System;
 using System.Collections.Generic;
 using JCG = J2N.Collections.Generic;
 
@@ -56,14 +55,6 @@ namespace Lucene.Net.Index
         // because it has public subclasses. So we are creating an internal constructor instead.
         internal BaseIndexFileFormatTestCase() { }
 #endif
-        // LUCENENET specific - optimized empty array creation
-        internal static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
 
         /// <summary>
         /// Returns the codec to run tests against </summary>
diff --git a/src/Lucene.Net.Tests/Util/TestArrayUtil.cs b/src/Lucene.Net.Tests/Util/TestArrayUtil.cs
index f89b71a..31eeef9 100644
--- a/src/Lucene.Net.Tests/Util/TestArrayUtil.cs
+++ b/src/Lucene.Net.Tests/Util/TestArrayUtil.cs
@@ -349,11 +349,8 @@ namespace Lucene.Net.Util
         [Test]
         public virtual void TestEmptyArraySort()
         {
-#if FEATURE_ARRAYEMPTY
-            int[] a = Array.Empty<int>();
-#else
-            int[] a = new int[0];
-#endif
+            int[] a = Arrays.Empty<int>();
+
             ArrayUtil.IntroSort(a);
             ArrayUtil.TimSort(a);
             ArrayUtil.IntroSort(a, Collections.ReverseOrder<int>());
diff --git a/src/Lucene.Net/Codecs/BlockTreeTermsReader.cs b/src/Lucene.Net/Codecs/BlockTreeTermsReader.cs
index c6aac58..a654054 100644
--- a/src/Lucene.Net/Codecs/BlockTreeTermsReader.cs
+++ b/src/Lucene.Net/Codecs/BlockTreeTermsReader.cs
@@ -1501,12 +1501,8 @@ namespace Lucene.Net.Codecs
                 private FST.Arc<BytesRef>[] arcs = new FST.Arc<BytesRef>[1];
 
                 // LUCENENET specific - optimized empty array creation
-                private static readonly Frame[] EMPTY_FRAMES =
-#if FEATURE_ARRAYEMPTY
-                    Array.Empty<Frame>();
-#else
-                    new Frame[0];
-#endif
+                private static readonly Frame[] EMPTY_FRAMES = Arrays.Empty<Frame>();
+
                 public SegmentTermsEnum(BlockTreeTermsReader.FieldReader outerInstance)
                 {
                     this.outerInstance = outerInstance;
diff --git a/src/Lucene.Net/Codecs/PostingsFormat.cs b/src/Lucene.Net/Codecs/PostingsFormat.cs
index bc503c9..a391345 100644
--- a/src/Lucene.Net/Codecs/PostingsFormat.cs
+++ b/src/Lucene.Net/Codecs/PostingsFormat.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Index;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
 using System;
 using System.Collections.Generic;
@@ -69,12 +70,7 @@ namespace Lucene.Net.Codecs
 
         /// <summary>
         /// Zero-length <see cref="PostingsFormat"/> array. </summary>
-        public static readonly PostingsFormat[] EMPTY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<PostingsFormat>();
-#else
-            new PostingsFormat[0];
-#endif
+        public static readonly PostingsFormat[] EMPTY = Arrays.Empty<PostingsFormat>();
 
         /// <summary>
         /// Unique name that's used to retrieve this format when
diff --git a/src/Lucene.Net/Document/Document.cs b/src/Lucene.Net/Document/Document.cs
index aa2c37d..4e5f186 100644
--- a/src/Lucene.Net/Document/Document.cs
+++ b/src/Lucene.Net/Document/Document.cs
@@ -1,4 +1,5 @@
 using Lucene.Net.Index;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
 using System;
 using System.Collections;
@@ -218,12 +219,7 @@ namespace Lucene.Net.Documents
         /// </summary>
         public IList<IIndexableField> Fields => fields;
 
-        private static readonly string[] NO_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
+        private static readonly string[] NO_STRINGS = Arrays.Empty<string>();
 
         /// <summary>
         /// Returns an array of values of the field specified as the method parameter.
diff --git a/src/Lucene.Net/Index/Fields.cs b/src/Lucene.Net/Index/Fields.cs
index f84807d..6b07854 100644
--- a/src/Lucene.Net/Index/Fields.cs
+++ b/src/Lucene.Net/Index/Fields.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -97,11 +98,6 @@ namespace Lucene.Net.Index
         /// <summary>
         /// Zero-length <see cref="Fields"/> array.
         /// </summary>
-        public static readonly Fields[] EMPTY_ARRAY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Fields>();
-#else
-            new Fields[0];
-#endif
+        public static readonly Fields[] EMPTY_ARRAY = Arrays.Empty<Fields>();
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Index/IndexFileDeleter.cs b/src/Lucene.Net/Index/IndexFileDeleter.cs
index d2d16e2..f246e17 100644
--- a/src/Lucene.Net/Index/IndexFileDeleter.cs
+++ b/src/Lucene.Net/Index/IndexFileDeleter.cs
@@ -122,14 +122,6 @@ namespace Lucene.Net.Index
             //LUCENENET TODO: This always returns true - probably incorrect
             writer == null || true /*Monitor.IsEntered(writer)*/;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly string[] EMPTY_STRINGS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<string>();
-#else
-            new string[0];
-#endif
-
         /// <summary>
         /// Initialize the deleter: find all previous commits in
         /// the <see cref="Directory"/>, incref the files they reference, call
@@ -166,7 +158,7 @@ namespace Lucene.Net.Index
 #pragma warning restore 168
             {
                 // it means the directory is empty, so ignore it.
-                files = EMPTY_STRINGS;
+                files = Arrays.Empty<string>();
             }
 
             if (currentSegmentsFile != null)
diff --git a/src/Lucene.Net/Index/MultiTermsEnum.cs b/src/Lucene.Net/Index/MultiTermsEnum.cs
index 5aaf144..ee15a7c 100644
--- a/src/Lucene.Net/Index/MultiTermsEnum.cs
+++ b/src/Lucene.Net/Index/MultiTermsEnum.cs
@@ -52,12 +52,7 @@ namespace Lucene.Net.Index
 
         public class TermsEnumIndex
         {
-            public static readonly TermsEnumIndex[] EMPTY_ARRAY =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<TermsEnumIndex>();
-#else
-                new TermsEnumIndex[0];
-#endif
+            public static readonly TermsEnumIndex[] EMPTY_ARRAY = Arrays.Empty<TermsEnumIndex>();
             internal int SubIndex { get; private set; }
             internal TermsEnum TermsEnum { get; private set; }
 
diff --git a/src/Lucene.Net/Index/ParallelCompositeReader.cs b/src/Lucene.Net/Index/ParallelCompositeReader.cs
index 013a841..8dd7743 100644
--- a/src/Lucene.Net/Index/ParallelCompositeReader.cs
+++ b/src/Lucene.Net/Index/ParallelCompositeReader.cs
@@ -1,4 +1,5 @@
 using J2N.Runtime.CompilerServices;
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -53,14 +54,6 @@ namespace Lucene.Net.Index
         private readonly bool closeSubReaders;
         private readonly ISet<IndexReader> completeReaderSet = new JCG.HashSet<IndexReader>(IdentityEqualityComparer<IndexReader>.Default);
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly IndexReader[] EMPTY_INDEXREADERS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<IndexReader>();
-#else
-            new IndexReader[0];
-#endif
-
         /// <summary>
         /// Create a <see cref="ParallelCompositeReader"/> based on the provided
         /// readers; auto-disposes the given <paramref name="readers"/> on <see cref="IndexReader.Dispose()"/>.
@@ -111,7 +104,7 @@ namespace Lucene.Net.Index
                     throw new ArgumentException("There must be at least one main reader if storedFieldsReaders are used.");
                 }
                 // LUCENENET: Optimized empty string array creation
-                return EMPTY_INDEXREADERS;
+                return Arrays.Empty<IndexReader>();
             }
             else
             {
diff --git a/src/Lucene.Net/Index/ReaderSlice.cs b/src/Lucene.Net/Index/ReaderSlice.cs
index 9d8cb7d..a4968cd 100644
--- a/src/Lucene.Net/Index/ReaderSlice.cs
+++ b/src/Lucene.Net/Index/ReaderSlice.cs
@@ -1,4 +1,4 @@
-using System;
+using Lucene.Net.Support;
 
 namespace Lucene.Net.Index
 {
@@ -28,12 +28,7 @@ namespace Lucene.Net.Index
     {
         /// <summary>
         /// Zero-length <see cref="ReaderSlice"/> array. </summary>
-        public static readonly ReaderSlice[] EMPTY_ARRAY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<ReaderSlice>();
-#else
-            new ReaderSlice[0];
-#endif
+        public static readonly ReaderSlice[] EMPTY_ARRAY = Arrays.Empty<ReaderSlice>();
 
         /// <summary>
         /// Document ID this slice starts from. </summary>
diff --git a/src/Lucene.Net/Index/Terms.cs b/src/Lucene.Net/Index/Terms.cs
index c86b758..60fa71c 100644
--- a/src/Lucene.Net/Index/Terms.cs
+++ b/src/Lucene.Net/Index/Terms.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 
@@ -169,11 +170,6 @@ namespace Lucene.Net.Index
 
         /// <summary>
         /// Zero-length array of <see cref="Terms"/>. </summary>
-        public static readonly Terms[] EMPTY_ARRAY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Terms>();
-#else
-            new Terms[0];
-#endif
+        public static readonly Terms[] EMPTY_ARRAY = Arrays.Empty<Terms>();
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Search/CachingCollector.cs b/src/Lucene.Net/Search/CachingCollector.cs
index c8b0dd0..d46ce9f 100644
--- a/src/Lucene.Net/Search/CachingCollector.cs
+++ b/src/Lucene.Net/Search/CachingCollector.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 
@@ -56,12 +57,7 @@ namespace Lucene.Net.Search
         /// <summary>
         /// NOTE: This was EMPTY_INT_ARRAY in Lucene
         /// </summary>
-        private static readonly int[] EMPTY_INT32_ARRAY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<int>();
-#else
-            new int[0];
-#endif
+        private static readonly int[] EMPTY_INT32_ARRAY = Arrays.Empty<int>();
 
         private class SegStart
         {
diff --git a/src/Lucene.Net/Search/FieldComparator.cs b/src/Lucene.Net/Search/FieldComparator.cs
index e571ea7..4f7703f 100644
--- a/src/Lucene.Net/Search/FieldComparator.cs
+++ b/src/Lucene.Net/Search/FieldComparator.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Diagnostics;
 using System.IO;
@@ -1408,19 +1409,9 @@ namespace Lucene.Net.Search
         public sealed class TermValComparer : FieldComparer<BytesRef>
         {
             // sentinels, just used internally in this comparer
-            private static readonly byte[] MISSING_BYTES =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<byte>();
-#else
-                new byte[0];
-#endif
-
-            private static readonly byte[] NON_MISSING_BYTES =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<byte>();
-#else
-                new byte[0];
-#endif
+            private static readonly byte[] MISSING_BYTES = Arrays.Empty<byte>();
+
+            private static readonly byte[] NON_MISSING_BYTES = Arrays.Empty<byte>();
 
             private BytesRef[] values;
             private BinaryDocValues docTerms;
diff --git a/src/Lucene.Net/Search/TopDocs.cs b/src/Lucene.Net/Search/TopDocs.cs
index 3a1f5d1..eac80c8 100644
--- a/src/Lucene.Net/Search/TopDocs.cs
+++ b/src/Lucene.Net/Search/TopDocs.cs
@@ -295,7 +295,7 @@ namespace Lucene.Net.Search
             ScoreDoc[] hits;
             if (availHitCount <= start)
             {
-                hits = EMPTY_SCOREDOCS;
+                hits = Arrays.Empty<ScoreDoc>();
             }
             else
             {
@@ -336,13 +336,5 @@ namespace Lucene.Net.Search
                 return new TopFieldDocs(totalHitCount, hits, sort.GetSort(), maxScore);
             }
         }
-
-        // LUCENENET specific - optimized empty array creation
-        private static readonly ScoreDoc[] EMPTY_SCOREDOCS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<ScoreDoc>();
-#else
-            new ScoreDoc[0];
-#endif
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Search/TopFieldCollector.cs b/src/Lucene.Net/Search/TopFieldCollector.cs
index 66acd0f..e8ac6ee 100644
--- a/src/Lucene.Net/Search/TopFieldCollector.cs
+++ b/src/Lucene.Net/Search/TopFieldCollector.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using Lucene.Net.Util;
 using System;
 using System.IO;
@@ -1128,12 +1129,7 @@ namespace Lucene.Net.Search
             }
         }
 
-        private static readonly ScoreDoc[] EMPTY_SCOREDOCS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<ScoreDoc>();
-#else
-            new ScoreDoc[0];
-#endif
+        private static readonly ScoreDoc[] EMPTY_SCOREDOCS = Arrays.Empty<ScoreDoc>();
 
         private readonly bool fillFields;
 
diff --git a/src/Lucene.Net/Search/TopScoreDocCollector.cs b/src/Lucene.Net/Search/TopScoreDocCollector.cs
index 05430bd..cd9c182 100644
--- a/src/Lucene.Net/Search/TopScoreDocCollector.cs
+++ b/src/Lucene.Net/Search/TopScoreDocCollector.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Diagnostics;
 
@@ -127,18 +128,10 @@ namespace Lucene.Net.Search
             protected override TopDocs NewTopDocs(ScoreDoc[] results, int start)
             {
                 // LUCENENET specific - optimized empty array creation
-                return results == null ? new TopDocs(m_totalHits, EMPTY_SCOREDOCS, float.NaN) : new TopDocs(m_totalHits, results);
+                return results == null ? new TopDocs(m_totalHits, Arrays.Empty<ScoreDoc>(), float.NaN) : new TopDocs(m_totalHits, results);
             }
         }
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly ScoreDoc[] EMPTY_SCOREDOCS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<ScoreDoc>();
-#else
-            new ScoreDoc[0];
-#endif
-
         // Assumes docs are scored out of order.
         private class OutOfOrderTopScoreDocCollector : TopScoreDocCollector
         {
@@ -233,7 +226,7 @@ namespace Lucene.Net.Search
             protected override TopDocs NewTopDocs(ScoreDoc[] results, int start)
             {
                 // LUCENENET specific - optimized empty array creation
-                return results == null ? new TopDocs(m_totalHits, EMPTY_SCOREDOCS, float.NaN) : new TopDocs(m_totalHits, results);
+                return results == null ? new TopDocs(m_totalHits, Arrays.Empty<ScoreDoc>(), float.NaN) : new TopDocs(m_totalHits, results);
             }
         }
 
diff --git a/src/Lucene.Net/Support/Arrays.cs b/src/Lucene.Net/Support/Arrays.cs
index baa5bbe..ce9ae93 100644
--- a/src/Lucene.Net/Support/Arrays.cs
+++ b/src/Lucene.Net/Support/Arrays.cs
@@ -169,5 +169,29 @@ namespace Lucene.Net.Support
             sb.Append(']');
             return sb.ToString();
         }
+
+        /// <summary>
+        /// Returns an empty array.
+        /// </summary>
+        /// <typeparam name="T">The type of the elements of the array.</typeparam>
+        /// <returns>An empty array.</returns>
+        // LUCENENET: Since Array.Empty<T>() doesn't exist in all supported platforms, we
+        // have this wrapper method to add support.
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T[] Empty<T>()
+        {
+#if FEATURE_ARRAYEMPTY
+            return Array.Empty<T>();
+#else
+            return EmptyArrayHolder<T>.EMPTY;
+#endif
+        }
+
+        private static class EmptyArrayHolder<T>
+        {
+#pragma warning disable CA1825 // Avoid zero-length array allocations.
+            public static readonly T[] EMPTY = new T[0];
+#pragma warning restore CA1825 // Avoid zero-length array allocations.
+        }
     }
 }
diff --git a/src/Lucene.Net/Util/Automaton/DaciukMihovAutomatonBuilder.cs b/src/Lucene.Net/Util/Automaton/DaciukMihovAutomatonBuilder.cs
index 166c58e..5cea9da 100644
--- a/src/Lucene.Net/Util/Automaton/DaciukMihovAutomatonBuilder.cs
+++ b/src/Lucene.Net/Util/Automaton/DaciukMihovAutomatonBuilder.cs
@@ -42,20 +42,11 @@ namespace Lucene.Net.Util.Automaton
         {
             /// <summary>
             /// An empty set of labels. </summary>
-            private static readonly int[] NO_LABELS =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<int>();
-#else
-                new int[0];
-#endif
+            private static readonly int[] NO_LABELS = Arrays.Empty<int>();
+
             /// <summary>
             /// An empty set of states. </summary>
-            private static readonly State[] NO_STATES =
-#if FEATURE_ARRAYEMPTY
-                Array.Empty<State>();
-#else
-                new State[0];
-#endif
+            private static readonly State[] NO_STATES = Arrays.Empty<State>();
 
             /// <summary>
             /// Labels of outgoing transitions. Indexed identically to <see cref="states"/>.
diff --git a/src/Lucene.Net/Util/Automaton/State.cs b/src/Lucene.Net/Util/Automaton/State.cs
index 5e50113..c1065b2 100644
--- a/src/Lucene.Net/Util/Automaton/State.cs
+++ b/src/Lucene.Net/Util/Automaton/State.cs
@@ -43,21 +43,13 @@ namespace Lucene.Net.Util.Automaton
     /// </summary>
     public class State : IComparable<State>, IEquatable<State> // LUCENENET specific: Implemented IEquatable, since this class is used in hashtables
     {
-        // LUCENENET specific - optimized empty array creation
-        private static readonly Transition[] EMPTY_TRANSITIONS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Transition>();
-#else
-            new Transition[0];
-#endif
-
         internal bool accept;
         [WritableArray]
         [SuppressMessage("Microsoft.Performance", "CA1819", Justification = "Lucene's design requires some writable array properties")]
         public Transition[] TransitionsArray => transitionsArray;
 
         // LUCENENET NOTE: Setter removed because it is apparently not in use outside of this class
-        private Transition[] transitionsArray = EMPTY_TRANSITIONS;
+        private Transition[] transitionsArray = Arrays.Empty<Transition>();
 
         internal int numTransitions = 0;// LUCENENET NOTE: Made internal because we already have a public property for access
 
@@ -80,7 +72,7 @@ namespace Lucene.Net.Util.Automaton
         /// </summary>
         internal void ResetTransitions()
         {
-            transitionsArray = EMPTY_TRANSITIONS;
+            transitionsArray = Arrays.Empty<Transition>();
             numTransitions = 0;
         }
 
diff --git a/src/Lucene.Net/Util/Bits.cs b/src/Lucene.Net/Util/Bits.cs
index 92ac748..3558cae 100644
--- a/src/Lucene.Net/Util/Bits.cs
+++ b/src/Lucene.Net/Util/Bits.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 
 namespace Lucene.Net.Util
@@ -42,12 +43,8 @@ namespace Lucene.Net.Util
 
     public static class Bits
     {
-        public static readonly IBits[] EMPTY_ARRAY =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<IBits>();
-#else
-            new IBits[0];
-#endif
+        public static readonly IBits[] EMPTY_ARRAY = Arrays.Empty<IBits>();
+
         /// <summary>
         /// Bits impl of the specified length with all bits set.
         /// </summary>
diff --git a/src/Lucene.Net/Util/BytesRef.cs b/src/Lucene.Net/Util/BytesRef.cs
index a8858b8..88ff684 100644
--- a/src/Lucene.Net/Util/BytesRef.cs
+++ b/src/Lucene.Net/Util/BytesRef.cs
@@ -1,4 +1,5 @@
 using J2N.Text;
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -47,12 +48,7 @@ namespace Lucene.Net.Util
     {
         /// <summary>
         /// An empty byte array for convenience </summary>
-        public static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
+        public static readonly byte[] EMPTY_BYTES = Arrays.Empty<byte>();
 
         /// <summary>
         /// The contents of the BytesRef. Should never be <c>null</c>.
diff --git a/src/Lucene.Net/Util/CharsRef.cs b/src/Lucene.Net/Util/CharsRef.cs
index 76c9704..d0120a6 100644
--- a/src/Lucene.Net/Util/CharsRef.cs
+++ b/src/Lucene.Net/Util/CharsRef.cs
@@ -1,4 +1,5 @@
 using J2N.Text;
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -41,12 +42,8 @@ namespace Lucene.Net.Util
     {
         /// <summary>
         /// An empty character array for convenience </summary>
-        public static readonly char[] EMPTY_CHARS =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<char>();
-#else
-            new char[0];
-#endif
+        public static readonly char[] EMPTY_CHARS = Arrays.Empty<char>();
+
         bool ICharSequence.HasValue => true;
 
         /// <summary>
diff --git a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
index de64801..8eee017 100644
--- a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
+++ b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
@@ -55,14 +55,6 @@ namespace Lucene.Net.Util
     {
         private readonly bool estimateRam;
 
-        // LUCENENET specific - optimized empty array creation
-        private static readonly Insanity[] EMPTY_INSANTITIES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<Insanity>();
-#else
-            new Insanity[0];
-#endif
-
         public FieldCacheSanityChecker()
         {
             /* NOOP */
@@ -113,7 +105,7 @@ namespace Lucene.Net.Util
         {
             if (null == cacheEntries || 0 == cacheEntries.Length)
             {
-                return EMPTY_INSANTITIES;
+                return Arrays.Empty<Insanity>();
             }
 
             if (estimateRam)
diff --git a/src/Lucene.Net/Util/Fst/FST.cs b/src/Lucene.Net/Util/Fst/FST.cs
index 39c0528..e3f9f98 100644
--- a/src/Lucene.Net/Util/Fst/FST.cs
+++ b/src/Lucene.Net/Util/Fst/FST.cs
@@ -1,4 +1,5 @@
 using J2N.Collections;
+using Lucene.Net.Support;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -105,12 +106,7 @@ namespace Lucene.Net.Util.Fst
         /// <seealso cref= #shouldExpand(UnCompiledNode) </seealso>
         internal const int FIXED_ARRAY_NUM_ARCS_DEEP = 10;*/
 
-        private int[] bytesPerArc =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<int>();
-#else
-            new int[0];
-#endif
+        private int[] bytesPerArc = Arrays.Empty<int>();
 
         /*// Increment version to change it
         private const string FILE_FORMAT_NAME = "FST";
diff --git a/src/Lucene.Net/Util/IntsRef.cs b/src/Lucene.Net/Util/IntsRef.cs
index 0b72186..2d1d5c5 100644
--- a/src/Lucene.Net/Util/IntsRef.cs
+++ b/src/Lucene.Net/Util/IntsRef.cs
@@ -45,12 +45,7 @@ namespace Lucene.Net.Util
         /// <para/>
         /// NOTE: This was EMPTY_INTS in Lucene
         /// </summary>
-        public static readonly int[] EMPTY_INT32S =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<int>();
-#else
-            new int[0];
-#endif
+        public static readonly int[] EMPTY_INT32S = Arrays.Empty<int>();
 
         /// <summary>
         /// The contents of the <see cref="Int32sRef"/>. Should never be <c>null</c>. 
diff --git a/src/Lucene.Net/Util/LongsRef.cs b/src/Lucene.Net/Util/LongsRef.cs
index 9d3fa2d..65c885c 100644
--- a/src/Lucene.Net/Util/LongsRef.cs
+++ b/src/Lucene.Net/Util/LongsRef.cs
@@ -45,12 +45,7 @@ namespace Lucene.Net.Util
         /// <para/>
         /// NOTE: This was EMPTY_LONGS in Lucene
         /// </summary>
-        public static readonly long[] EMPTY_INT64S =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<long>();
-#else
-            new long[0];
-#endif
+        public static readonly long[] EMPTY_INT64S = Arrays.Empty<long>();
 
         /// <summary>
         /// The contents of the <see cref="Int64sRef"/>. Should never be <c>null</c>. 
diff --git a/src/Lucene.Net/Util/PagedBytes.cs b/src/Lucene.Net/Util/PagedBytes.cs
index 495ec7c..123096e 100644
--- a/src/Lucene.Net/Util/PagedBytes.cs
+++ b/src/Lucene.Net/Util/PagedBytes.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -51,12 +52,7 @@ namespace Lucene.Net.Util
         private byte[] currentBlock;
         private readonly long bytesUsedPerBlock;
 
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
+        private static readonly byte[] EMPTY_BYTES = Arrays.Empty<byte>();
 
         /// <summary>
         /// Provides methods to read <see cref="BytesRef"/>s from a frozen
diff --git a/src/Lucene.Net/Util/WAH8DocIdSet.cs b/src/Lucene.Net/Util/WAH8DocIdSet.cs
index 0da58af..656680e 100644
--- a/src/Lucene.Net/Util/WAH8DocIdSet.cs
+++ b/src/Lucene.Net/Util/WAH8DocIdSet.cs
@@ -87,17 +87,10 @@ namespace Lucene.Net.Util
         /// <summary>
         /// Default index interval. </summary>
         public const int DEFAULT_INDEX_INTERVAL = 24;
-
-        // LUCENENET specific - optimized empty array creation
-        private static readonly byte[] EMPTY_BYTES =
-#if FEATURE_ARRAYEMPTY
-            Array.Empty<byte>();
-#else
-            new byte[0];
-#endif
-
+        
         private static readonly MonotonicAppendingInt64Buffer SINGLE_ZERO_BUFFER = LoadSingleZeroBuffer();
-        private static readonly WAH8DocIdSet EMPTY = new WAH8DocIdSet(EMPTY_BYTES, 0, 1, SINGLE_ZERO_BUFFER, SINGLE_ZERO_BUFFER);
+        // LUCENENET specific - optimized empty array creation
+        private static readonly WAH8DocIdSet EMPTY = new WAH8DocIdSet(Arrays.Empty<byte>(), 0, 1, SINGLE_ZERO_BUFFER, SINGLE_ZERO_BUFFER);
         private static MonotonicAppendingInt64Buffer LoadSingleZeroBuffer() // LUCENENET: Avoid static constructors (see https://github.com/apache/lucenenet/pull/224#issuecomment-469284006)
         {
             var buffer = new MonotonicAppendingInt64Buffer(1, 64, PackedInt32s.COMPACT);