2015-04-14 12 views
17

stavo scrivendo una funzione per gli array 2d booleani:Qual è la differenza tra Array {Bool} e BitArray in Julia e come sono correlati?

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

valutazione e test con

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

rendimenti

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

Ovviamente, randbool() genera un BitArray, mentre ho assunto randbool() darebbe un Array{Bool}.

Come sono correlati Array{Bool} e BitArray? Perché entrambi esistono?

Posso scrivere foo() in modo che accetti entrambi i tipi di input utilizzando un unico metodo (poiché non riesco a vedere una differenza)?

+3

La tua ipotesi sul comportamento di 'randbool' non è irragionevole - è un nome piuttosto brutto! È stato deprecato in 0.4 e rinominato in 'bitrand' (il che suona più come se creasse un BitArray). E c'è un nuovo metodo 'rand (Bool, ...)' per creare esplicitamente un array di 'Bool'. È possibile iniziare a utilizzare queste nuove definizioni in 0.3 con il pacchetto [Compat] (https://github.com/JuliaLang/Compat.jl). –

risposta

18

Un Array{Bool} memorizza ogni valore true/false come Bool, che è rappresentato internamente come UInt8. Quindi se il tuo array ha elementi N, ci vorranno i byte N per memorizzarlo.

A BitArray memorizza ogni valore true/false come un singolo bit, con (concettualmente) 8 di essi raggruppati in un singolo UInt8. Di conseguenza, per memorizzare l'array sono necessari solo N/8 byte. Un BitArray ha anche metodi definiti che gestiscono tutte le operazioni di bit-twiddling necessarie per te.

A seconda dell'operazione, gli BitArray s sono talvolta più lenti del corrispondente Array{Bool} e talvolta più veloci. Ma in generale le differenze di prestazioni sono piuttosto piccole, quindi ha senso usare BitArray s a meno che non si abbia una ragione specifica per non farlo. Ma nel complesso sono abbastanza intercambiabili.

Si noti che entrambi sono sottotipi di AbstractArray{Bool}:

julia> BitArray <: AbstractArray{Bool} 
true 

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

Ciò rende più semplice per scrivere metodi generici che prendono uno dei due.

+2

'AbstractArray {Bool}' è esattamente il tipo che stavo cercando. – reschu