# View and boolean indexing

**URL:** <https://discourse.julialang.org/t/view-and-boolean-indexing/96609>\
**Category:** Performance\
**Tags:** array\
**Created:** [March 25, 2023, 8:33pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609 "2023-03-25T20:33:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [March 25, 2023, 8:33pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609/1 "2023-03-25T20:33:29Z")

</div>

This old thread brought up an important question about why `view(x,boolean_indices)` is slow. One reply said “So the TLDR is: Mixing views and logical indices is currently no good.”

It seems to be that we still have this issue. Any updates?

> [@Confused about performance interaction between @view and logical (Boolean) indexing](https://discourse.julialang.org/t/confused-about-performance-interaction-between-view-and-logical-boolean-indexing/23120):
>
> I’m trying to understand the interaction between array views and Boolean indexing. In general, my understanding (and experience thus far) is that views generally increasing performance when you’re not modifying the array slices. For example: x = collect(1:1000) @btime z = x[50:200]; 107.278 ns (1 allocation: 1.33 KiB) @btime z = @view x[50:200]; 19.084 ns (1 allocation: 48 bytes) However, now do the equivalent operations using Boolean indexing, and the performance is reversed: w = (x …

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 25, 2023, 8:36pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609/2 "2023-03-25T20:36:21Z")

</div>

> [@Paul\_Soderlind](#):
>
> why `view(x,boolean_indices)` is slow.

How could it be fast? If `y = view(x,boolean_indices)` does not allocate an index array (which is what it does), how could you get `y[i]` without looping sequentially through `x`? And the combination of allocating an index array and doing a double indirection on every `getindex` seems almost guaranteed to be slow…

---

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [March 25, 2023, 8:49pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609/3 "2023-03-25T20:49:37Z")

</div>

Thanks. Probably deserves a comment in the docs. (Maybe there is one, but it has so far escaped me.)

For my type of applications (statistics, where some obs are invalid and flagged by a bool), this means that `view()` isn’t very interesting. That’s OK, although it causes some issues in a threaded setting (where allocations are particularly bad, it seems).

---

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [March 26, 2023, 1:17pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609/4 "2023-03-26T13:17:46Z")

</div>

On 2nd thought, I realise that `view(x::Matrix,inds,:)` is actually very useful even if `inds` is a bitvector. Relatively small allocations (essentially the same as for a vector `x`) and quick.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 26, 2023, 5:14pm UTC](https://discourse.julialang.org/t/view-and-boolean-indexing/96609/5 "2023-03-26T17:14:25Z")

</div>

> [@Paul\_Soderlind](#):
>
> For my type of applications (statistics, where some obs are invalid and flagged by a bool), this means that `view()` isn’t very interesting.

If you need consecutive array-like indices, there’s no way around allocating an index array — that’s what `view()` does.

If you only need iteration, and no indexing at all, `Iterators.filter()` can help.

If you do need indexing, and keeping the same indices as in the original array is fine, look at allocation-free `skip()`:

```julia
julia> using Skipper

julia> data = [
    (val=1, isbad=false),
    (val=2, isbad=true),
    (val=3, isbad=false)
]

julia> data_good = skip(x -> x.isbad, data)

julia> length(data_good)
2

julia> collect(eachindex(data_good))
2-element Vector{Int64}:
 1
 3

julia> data_good[3]
(val = 3, isbad = false)

```
