В чем разница между Array{Bool} и BitArray в Julia и как они связаны?

я писал функцию для булевых 2d-массивов:

function foo(A::Array{Bool,2})
   ...
end

оценка и тестирование с

A = randbool(3,3)
foo(A)

возвращает

ERROR: 'foo' has no method matching foo(::BitArray{2})

очевидно, randbool() создает BitArray, тогда как я предполагал randbool() даст Array{Bool}.

как Array{Bool} и BitArray связаны? Почему они оба существуют?

я могу написать foo() таким образом, что он принимает оба типа ввода, используя один метод (так как я не вижу разница)?

1 ответов


An Array{Bool} каждый true/false значение Bool, который представлен внутренне как UInt8. Поэтому, если Ваш массив имеет N элементы, потребуется N байты для его хранения.

A BitArray каждый true/false значение как один бит ,причем (концептуально) 8 из них упакованы в один UInt8. Следовательно, требуется только N/8 байт для хранения массива. А BitArray также определены методы, которые обрабатывают все необходимые битовые операции для вы.

в зависимости от операции, BitArrays иногда медленнее, чем соответствующий Array{Bool}, а иногда и быстрее. Но по большому счету различия в производительности довольно малы, поэтому имеет смысл использовать BitArrayС, Если у вас нет особых причин не делать этого. Но в целом они довольно взаимозаменяемы.

обратите внимание, что оба являются подтипами AbstractArray{Bool}:

julia> BitArray <: AbstractArray{Bool}
true

julia> Array{Bool} <: AbstractArray{Bool}
true

это позволяет легко писать общие методы, которые принимают либо один.