# Efficient way to get indices of true elements from BitArray

**URL:** <https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731>\
**Category:** New to Julia\
**Tags:** indexing\
**Created:** [February 3, 2022, 2:14pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731 "2022-02-03T14:14:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rmsmsgood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rmsmsgood/32/20544_2.png) [@rmsmsgood](https://discourse.julialang.org/u/rmsmsgood)\
**Post date:** [February 3, 2022, 2:14pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/1 "2022-02-03T14:14:42Z")

</div>

I usually use the following:

```julia
x = rand(Bool, 10)
(1:length(x))[x]

```

Result:

```julia
julia> x = rand(Bool, 10)
10-element Vector{Bool}:
 0
 1
 0
 0
 0
 1
 1
 0
 0
 0

julia> (1:length(x))[x]
3-element Vector{Int64}:
 2
 6
 7

```

But i think this is inefficient and slow, is there better way?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 3, 2022, 2:18pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/2 "2022-02-03T14:18:52Z")

</div>

[`findall`](https://docs.julialang.org/en/v1/base/arrays/#Base.findall-Tuple%7BAny%7D) is how I’d do this and where I’d expect an optimization to appear if one existed… but there’s not a BitArray specific optimization there now.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [February 3, 2022, 2:33pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/3 "2022-02-03T14:33:47Z")

</div>

Why do you think it’s slow? I agree with Matt that it’s a slightly unusual way to write `findall`, but it seems to give the same performance.

```julia
julia> x = rand(Bool, 1_000_000);

julia> using BenchmarkTools

julia> @btime findall($x);
  4.927 ms (2 allocations: 3.81 MiB)

julia> @btime (1:length($x))[$x];
  4.479 ms (2 allocations: 3.81 MiB)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 3, 2022, 2:56pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/4 "2022-02-03T14:56:29Z")

</div>

> [@rmsmsgood](#):
>
> `x = rand(Bool, 10)`

Side note: this is not a `BitArray`, it is a `Vector{Bool}`, where each element takes up one byte.

If you want an actual `BitArray`, with 8 elements per byte, you can do

```julia
rand(10) .< 0.5

```

or, probably more efficiently:

```julia
using Random
bitrand(10)

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 3, 2022, 2:59pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/5 "2022-02-03T14:59:35Z")

</div>

What you’re benchmarking there is `Vector{Bool}`. I had thought there might be some performance left on the table without a BitArray-specific bit fiddling method… but this looks pretty good: the `BitArray` is beating a `Vector{Bool}` by 10x.

```julia
julia> using BenchmarkTools

julia> x = rand(Bool, 1_000_000);

julia> y = BitArray(x);

julia> @btime findall($x);
  4.126 ms (2 allocations: 3.82 MiB)

julia> @btime findall($y);
  460.060 μs (2 allocations: 3.82 MiB)

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [February 3, 2022, 3:00pm UTC](https://discourse.julialang.org/t/efficient-way-to-get-indices-of-true-elements-from-bitarray/75731/6 "2022-02-03T15:00:58Z")

</div>

I don’t see quite such a large discrepancy (more like 5x, might be CPU dependent?), but I do see `findall` outperforming the index-into-a-range solution for `BitArray`:

```julia
julia> @btime (1:length($y))[$y];
  905.300 μs (2 allocations: 3.82 MiB)

julia> @btime findall($y);
  687.100 μs (2 allocations: 3.82 MiB)

```
