# Sum over view of BitArray

**URL:** <https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585>\
**Category:** Performance\
**Created:** [June 3, 2025, 3:34am UTC](https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585 "2025-06-03T03:34:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jerry\_ji](https://avatars.discourse-cdn.com/v4/letter/j/e36b37/32.png) [@jerry\_ji](https://discourse.julialang.org/u/jerry_ji)\
**Post date:** [June 3, 2025, 3:34am UTC](https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585/1 "2025-06-03T03:34:03Z")

</div>

q=trues(10000)  
d=view(q,1:10000)

@btime sum($q)  
17.034 ns (0 allocations: 0 bytes)  
10000

@btime sum($d)  
2.678 μs (0 allocations: 0 bytes)  
10000

how can i improve performance of sum over continuous subset of a BitArrary?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 3, 2025, 4:51am UTC](https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585/2 "2025-06-03T04:51:42Z")

</div>

I think the issue here is that `BitArray` is designed for elements to be accessed in bulk, not individually. This allows for a very efficient sum.  
When you take a view of it, you create a wrapper that implements individual `getindex`, but more methods would probably be needed to make reductions like sum fast.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 3, 2025, 5:30am UTC](https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585/3 "2025-06-03T05:30:25Z")

</div>

Specifically, `BitArray` internally contains a `Vector{UInt64}` (157 64-bit chunks for 10000 bits), and its `sum` dispatches to an internal `Base.bitcount` that works on these 157 chunks.

```julia
sum(a::AbstractArray{Bool}; kw...) =
    isempty(kw) ? count(a) : reduce(add_sum, a; kw...)
...
_count(::typeof(identity), B::BitArray, ::Colon, init) = bitcount(B.chunks; init)

function bitcount(Bc::Vector{UInt64}; init::T=0) where {T}
    n::T = init
    @inbounds for i = 1:length(Bc)
        n = (n + count_ones(Bc[i])) % T
    end
    return n
end

```

Wrappers of `BitArray`, such as views, go over 10000 elements, accessing each chunk 64 times. Since the `SubArray` type made by `view` is not a continuous subset in general, e.g. `view(q, 1:7:10000)`, it can’t use the same chunk strategy. I wonder if `UnitRange` views of dense vectors are always dense and _could_ be separate dense types.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [June 3, 2025, 8:39am UTC](https://discourse.julialang.org/t/sum-over-view-of-bitarray/129585/4 "2025-06-03T08:39:39Z")

</div>

> [@Benny](#):
>
> I wonder if `UnitRange` views of dense vectors are always dense and _could_ be separate dense types.

That’s already a thing:

> <https://github.com/JuliaLang/julia/blob/9108dd08a572e394854d85aa0b2b680cc6a591c3/base/subarray.jl#L320-L321>

> <https://github.com/JuliaLang/julia/blob/9108dd08a572e394854d85aa0b2b680cc6a591c3/base/subarray.jl#L343-L346>

But for a subarray of `BitArray` that’s not enough to ensure you’re reading whole bytes, since also the first element and the span are relevant.
