# Why mul! is so fast with BitVector?

**URL:** <https://discourse.julialang.org/t/why-mul-is-so-fast-with-bitvector/31629>\
**Category:** Performance\
**Tags:** question, linearalgebra\
**Created:** [November 28, 2019, 4:17pm UTC](https://discourse.julialang.org/t/why-mul-is-so-fast-with-bitvector/31629 "2019-11-28T16:17:44Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [November 28, 2019, 4:17pm UTC](https://discourse.julialang.org/t/why-mul-is-so-fast-with-bitvector/31629/1 "2019-11-28T16:17:44Z")

</div>

Consider the following example code:

```julia
using LinearAlgebra, BenchmarkTools

n = 200
xb = BitVector(rand(Bool, n))
xf = Float32.(xb)
W = randn(Float32,n,n)
y = zeros(Float32,n);

function mymul!(y, A, x)
    y .= 0
    @inbounds for j = 1:length(x)
        @simd for i = 1:length(y)
            #y[i] = muladd(A[i,j], x[j], y[i])
            y[i] += A[i,j] * x[j]
        end
    end
end

```

Here I find the following benchmarks:

```julia
@btime mymul!($y, $W, $xf); # 4.542 μs (0 allocations: 0 bytes)
@btime mul!($y, $W, $xf); # 7.541 μs (0 allocations: 0 bytes)
@btime mymul!($y, $W, $xb); # 15.586 μs (0 allocations: 0 bytes) (why?)
@btime mul!($y, $W, $xb); # 7.864 μs (0 allocations: 0 bytes)

```

So why is `mymul!` so slow when it is fed with a BitVector, as compared to `mul!` from LinearAlgebra?

Note that this question is very similar to [Why mul! is so fast?](https://discourse.julialang.org/t/why-mul-is-so-fast/31436). But in that thread I preferred to focus on Float64 arguments to simplify. Here I am referring to a difference specifically for BitVector arguments. I expect that the reason here will be different that in that thread because of the way the bools are stored as bits in a BitVector. Also note that I didn’t find such a big difference here when using Float64 instead of Float32, and I’m not sure how relevant that is.

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 29, 2019, 12:45am UTC](https://discourse.julialang.org/t/why-mul-is-so-fast-with-bitvector/31629/2 "2019-11-29T00:45:49Z")

</div>

It’s probably the conversion from `BitVector` to `Float32`. Here’s another way to do it.

```julia
function mymul!(y, A, x::BitVector)
    y .= 0
    for j in 1:length(x)
        @inbounds x[j] && (y .+= @view A[:,j])
    end
end

```

Quite a bit faster.
