# Meta-programming an if-else statement of user-defined length

**URL:** <https://discourse.julialang.org/t/meta-programming-an-if-else-statement-of-user-defined-length/53525>\
**Category:** Performance\
**Tags:** question, package\
**Created:** [January 18, 2021, 8:47am UTC](https://discourse.julialang.org/t/meta-programming-an-if-else-statement-of-user-defined-length/53525 "2021-01-18T08:47:22Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [January 18, 2021, 9:49am UTC](https://discourse.julialang.org/t/meta-programming-an-if-else-statement-of-user-defined-length/53525/7 "2021-01-18T09:49:01Z")

</div>

When I tried to reproduce the result, I guess I figured out another possible source of slowdown, it’s `Options` type.

With overall setup

```julia
function BINOP!(x::Array{Float32, 1}, y::Array{Float32, 1}, i::Int, clen::Int, options::Options)
    op = options.binops[i]
    BINOP!(op, x, y, clen, options)
end

function BINOP!(op::F, x::Array{Float32, 1}, y::Array{Float32, 1}, clen::Int, options::Options) where F
    @inbounds @simd for j=1:clen
        x[j] = op(x[j], y[j])
    end
end

function BINOP2!(x, y, i, clen, options)
    if i == 1
        @inbounds @simd for j=1:clen
            x[j] = (+)(x[j], y[j])
        end
    end
end

x = rand(Float32, 100)
y = rand(Float32, 100)
clen = length(x)

julia> @btime BINOP2!($x, $y, 1, $clen, $options)
  7.923 ns (0 allocations: 0 bytes)

```

I have tried three versions  
1.

```julia
struct Options
  binops
end

options = Options([+, -, *])
julia> @btime BINOP!($x, $y, 1, $clen, $options)
  44.011 ns (1 allocation: 16 bytes)

```

1. 

```julia
struct Options{T}
    binops::T
end
options = Options([+, -, *])

julia> @btime BINOP!($x, $y, 1, $clen, $options)
  31.602 ns (1 allocation: 16 bytes)

```

1. 

```julia
struct Options{T}
    binops::T
end
options = Options((+, -, *))

julia> @btime BINOP!($x, $y, 1, $clen, $options)
  23.229 ns (0 allocations: 0 bytes)

```

So, of all of this versions, fully typed tuple version of operations is the fastest. I think the difference `23 - 8 = 15` ns is the price that one have to pay to figure out `op` dynamically and it can’t be improved further.

If this performance is not enough then closest to this issue is union-splitting and write macro along the lines of [ManualDispatch.jl](https://github.com/jlapeyre/ManualDispatch.jl) or [this snippet](https://discourse.julialang.org/t/macro-to-write-function-with-many-conditionals/51616/8). But for it to work, all operations should be defined at compile time.

---

_[View the full topic](https://discourse.julialang.org/t/meta-programming-an-if-else-statement-of-user-defined-length/53525)._
