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 85f824c6323d843af3d5136d4aaff3fdeafb439a
Author: Shad Storhaug <[email protected]>
AuthorDate: Sat Dec 14 18:10:06 2019 +0700

    Lucene.Net.Support.BitArrayExtensions::Cardinality(): Replaced 
implementation with one that benchmarked more than 3x faster, at the cost of a 
small amount of RAM
---
 src/Lucene.Net/Support/BitArrayExtensions.cs | 36 +++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/Lucene.Net/Support/BitArrayExtensions.cs 
b/src/Lucene.Net/Support/BitArrayExtensions.cs
index 21e322d..e9c36c1 100644
--- a/src/Lucene.Net/Support/BitArrayExtensions.cs
+++ b/src/Lucene.Net/Support/BitArrayExtensions.cs
@@ -143,18 +143,48 @@ namespace Lucene.Net.Support
         }
 
         /// <summary>
-        /// Returns the number of bits set to true in this BitSet.
+        /// Returns the number of bits set to <c>true</c> in this <see 
cref="BitArray"/>.
         /// </summary>
-        /// <param name="bits">The BitArray object.</param>
-        /// <returns>The number of bits set to true in this BitSet.</returns>
+        /// <param name="bits">This <see cref="BitArray"/>.</param>
+        /// <returns>The number of bits set to true in this <see 
cref="BitArray"/>.</returns>
         public static int Cardinality(this BitArray bits)
         {
+            if (bits == null)
+                throw new ArgumentNullException(nameof(bits));
             int count = 0;
+
+#if NETSTANDARD1_6
             for (int i = 0; i < bits.Length; i++)
             {
                 if (bits[i])
                     count++;
             }
+#else
+            int bitsLength = bits.Length;
+            int[] ints = new int[(bitsLength >> 5) + 1];
+            int intsLength = ints.Length;
+            int c;
+
+            bits.CopyTo(ints, 0);
+
+            // fix for not truncated bits in last integer that may have been 
set to true with SetAll()
+            ints[intsLength - 1] &= ~(-1 << (bitsLength % 32));
+
+            for (int i = 0; i < intsLength; i++)
+            {
+                c = ints[i];
+
+                // magic 
(http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel)
+                unchecked
+                {
+                    c -= (c >> 1) & 0x55555555;
+                    c = (c & 0x33333333) + ((c >> 2) & 0x33333333);
+                    c = ((c + (c >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+                }
+
+                count += c;
+            }
+#endif
             return count;
         }
 

Reply via email to