# Switching two elements in array, vcat getting flagged as runtime-dispatch?

**URL:** https://discourse.julialang.org/t/switching-two-elements-in-array-vcat-getting-flagged-as-runtime-dispatch/95407
**Category:** General Usage
**Created:** [March 1, 2023, 9:17pm UTC](https://discourse.julialang.org/t/switching-two-elements-in-array-vcat-getting-flagged-as-runtime-dispatch/95407 "2023-03-01T21:17:52Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![hshackle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hshackle/32/47114_2.png) [@hshackle](https://discourse.julialang.org/u/hshackle)
#### Post date: [March 1, 2023, 9:17pm UTC](https://discourse.julialang.org/t/switching-two-elements-in-array-vcat-getting-flagged-as-runtime-dispatch/95407/1 "2023-03-01T21:17:53Z")

</div>

I currently have the following line of code in a simulation:

```julia
function exchangeBits(n::BitVector, i::Int, j::Int)
    # Returns a copy of n with the ith and jth bits exchanged
    if i < j
        m = n[vcat(1:(i - 1), j, i + 1:(j - 1), i, j + 1:end)]
    else
        m = n[vcat(1:(j - 1), i, j + 1:(i - 1), j, i + 1:end)]
    end
    return m
end

```

Running the full simulation through `@profview` gives a Flamegraph with a substantial amount of space taken up by this function, and it looks like the following:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/0/905c6bf0d14b848fce54da5b9b3ace1482c4bbab.png)

The way I understand this is that the function, in particular the usage of `vcat`, is somehow not type-stable and that I should find an alternative method. Is this correct? If so, what exactly is the problem with `vcat` in this context?

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [March 1, 2023, 9:41pm UTC](https://discourse.julialang.org/t/switching-two-elements-in-array-vcat-getting-flagged-as-runtime-dispatch/95407/2 "2023-03-01T21:41:08Z")

</div>

~~If I inspect the `@code_warntype` it claims to be type stable. But from the `@btime` below, I’d believe it’s actually unstable like the profiler suggests.~~ EDIT: The internals of `vcat` appear to be unstable in this situation. It looks like a loop in `LinearAlgebra._vcat` is to blame.

In any case, I’ll recommend this much faster version:

```julia
function exchangeBits2(n::BitVector, i::Int, j::Int)
    m = copy(n)
    m[j],m[i] = m[i],m[j] # swap entries i and j
    return m
end

```

```julia-repl
julia> using BenchmarkTools

julia> z = rand(500) .< 0.5;

julia> @btime exchangeBits($z,$10,$20);
  6.440 μs (108 allocations: 7.64 KiB)

julia> @btime exchangeBits2($z,$10,$20);
  39.697 ns (2 allocations: 160 bytes)

```

Dispatch aside, the big issue with the `vcat`-indexing version is that `vcat` builds a new array. You then use this new array to index `n` to make yet-another array. This is terribly wasteful. It’s also expensive to index a `BitVector` this way because of how it’s represented in memory (as individual bits, which take some effort to extract from the bytes that store them). Copying the whole thing and making the two little changes you want is much easier.

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [March 1, 2023, 10:25pm UTC](https://discourse.julialang.org/t/switching-two-elements-in-array-vcat-getting-flagged-as-runtime-dispatch/95407/3 "2023-03-01T22:25:41Z")

</div>

Opened as issue [#48850](https://github.com/JuliaLang/julia/issues/48850). That issue currently can be avoided via this definition that replaces `i` and `j` in the `vcat` calls with `i:i` and `j:j`, so that there aren’t mixtures of `Number` and `UnitRange` arguments:

```julia
function exchangeBits1(n::BitVector, i::Int, j::Int)
    # Returns a copy of n with the ith and jth bits exchanged
    if i < j
        m = n[vcat(1:(i - 1), j:j, i + 1:(j - 1), i:i, j + 1:end)]
    else
        m = n[vcat(1:(j - 1), i:i, j + 1:(i - 1), j:j, i + 1:end)]
    end
    return m
end

```

```julia-repl
julia> @btime exchangeBits1($z,$10,$20);
  1.240 μs (8 allocations: 4.38 KiB)

```

Note that this is still much slower than the suggested `exchangeBits2` given above.
