From 3f7ff29a0f7a1211d9c2d773dba0f096c8eb976b Mon Sep 17 00:00:00 2001 From: Chris Thompson Date: Mon, 4 Apr 2022 09:14:54 -0600 Subject: [PATCH 1/3] Use each_byte to significantly reduce memory requirements --- lib/bitarray-array.rb | 2 +- lib/bitarray.rb | 2 +- test/test_bitarray.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bitarray-array.rb b/lib/bitarray-array.rb index 7988fa8..d5bd907 100644 --- a/lib/bitarray-array.rb +++ b/lib/bitarray-array.rb @@ -45,6 +45,6 @@ def each_byte # Returns the total number of bits that are set # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) def total_set - @field.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } + @field.each_byte.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } end end diff --git a/lib/bitarray.rb b/lib/bitarray.rb index ebfe269..01b5c2c 100644 --- a/lib/bitarray.rb +++ b/lib/bitarray.rb @@ -49,7 +49,7 @@ def each_byte # Returns the total number of bits that are set # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) def total_set - @field.bytes.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } + @field.each_byte.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } end def byte_position(position) diff --git a/test/test_bitarray.rb b/test/test_bitarray.rb index 3a3c334..157453c 100644 --- a/test/test_bitarray.rb +++ b/test/test_bitarray.rb @@ -1,5 +1,5 @@ require "minitest/autorun" -require "bitarray" +require_relative "../lib/bitarray" class TestBitArray < Minitest::Test def setup From f2681ddb28e681a556816d64290b0d9c8ca31d2d Mon Sep 17 00:00:00 2001 From: Chris Thompson Date: Mon, 4 Apr 2022 09:17:23 -0600 Subject: [PATCH 2/3] Use faster bit counting algorithm --- lib/bitarray-array.rb | 5 +++-- lib/bitarray.rb | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/bitarray-array.rb b/lib/bitarray-array.rb index d5bd907..c4e6272 100644 --- a/lib/bitarray-array.rb +++ b/lib/bitarray-array.rb @@ -43,8 +43,9 @@ def each_byte end # Returns the total number of bits that are set - # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) + # Use Brian Kernighan's way, see + # https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan def total_set - @field.each_byte.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } + @field.each_byte.inject(0) { |a, byte| (a += 1; byte &= byte - 1) while byte > 0 ; a } end end diff --git a/lib/bitarray.rb b/lib/bitarray.rb index 01b5c2c..780629c 100644 --- a/lib/bitarray.rb +++ b/lib/bitarray.rb @@ -47,9 +47,10 @@ def each_byte end # Returns the total number of bits that are set - # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) + # Use Brian Kernighan's way, see + # https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan def total_set - @field.each_byte.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } + @field.each_byte.inject(0) { |a, byte| (a += 1; byte &= byte - 1) while byte > 0 ; a } end def byte_position(position) From 7b281a1dc16e618ac61b562b497cc28f8203608c Mon Sep 17 00:00:00 2001 From: Peter Cooper Date: Mon, 4 Apr 2022 17:20:27 +0100 Subject: [PATCH 3/3] Version update --- Gemfile.lock | 21 --------------------- lib/bitarray-array.rb | 2 +- lib/bitarray.rb | 2 +- 3 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index bce8c09..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,21 +0,0 @@ -PATH - remote: . - specs: - bitarray (1.2.0) - -GEM - remote: https://rubygems.org/ - specs: - minitest (5.10.1) - rake (12.0.0) - -PLATFORMS - ruby - -DEPENDENCIES - bitarray! - minitest - rake - -BUNDLED WITH - 1.16.3 diff --git a/lib/bitarray-array.rb b/lib/bitarray-array.rb index c4e6272..2191ffb 100644 --- a/lib/bitarray-array.rb +++ b/lib/bitarray-array.rb @@ -3,7 +3,7 @@ class BitArray attr_reader :field include Enumerable - VERSION = "1.2.0" + VERSION = "1.3.0" ELEMENT_WIDTH = 32 def initialize(size, field = nil) diff --git a/lib/bitarray.rb b/lib/bitarray.rb index 780629c..992d753 100644 --- a/lib/bitarray.rb +++ b/lib/bitarray.rb @@ -3,7 +3,7 @@ class BitArray attr_reader :field include Enumerable - VERSION = "1.2.0" + VERSION = "1.3.0" def initialize(size, field = nil, reverse_byte: true) @size = size