# Function created by factory function

**URL:** https://discourse.julialang.org/t/function-created-by-factory-function/23154
**Category:** Performance
**Created:** [April 15, 2019, 6:54am UTC](https://discourse.julialang.org/t/function-created-by-factory-function/23154 "2019-04-15T06:54:29Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [April 15, 2019, 6:54am UTC](https://discourse.julialang.org/t/function-created-by-factory-function/23154/1 "2019-04-15T06:54:29Z")

</div>

I have a type of which I want to create specific instances. To illustrate why I want this, think of a `Car` with fields `model::String`, `year::Int`, `acceleration::Function`. So there’s some “identifier” fields, some “parameter” fields, and then there’s fields holding a function. Here, `acceleration` could be a function of current speed and accelerator-pedal position.

I could be using “empty” subtypes of a single abstract type `Car`, but that does not work out well later on (ran into dynamic dispatch, I guess). So my current idea are factory functions, for example `FordModelT` that creates an appropriate instance of `Car`. The problem is the performance of the `::Function` fields. Consider this simple example:

```julia
struct TheType
    f::Function
end

# the original function
function fun(ϑ)
    c_ν = (1.99218000e-05, 3.29378459e-03, -4.11466399e-02)
    return (c_ν[1] + (c_ν[2] + c_ν[3]/ϑ)/ϑ)/ϑ
end

# the function as a captured variable
function Factory1()
    function fun(ϑ)
        c_ν = (1.99218000e-05, 3.29378459e-03, -4.11466399e-02)
        return (c_ν[1] + (c_ν[2] + c_ν[3]/ϑ)/ϑ)/ϑ
    end
    return TheType(fun)
end

# accessing captured variable in return expression of function
function Factory2()
    c_ν = (1.99218000e-05, 3.29378459e-03, -4.11466399e-02)
    return TheType(ϑ -> (c_ν[1] + (c_ν[2] + c_ν[3]/ϑ)/ϑ)/ϑ)
end

# quoting parameters into return expression
function Factory3()
    c_ν = (1.99218000e-05, 3.29378459e-03, -4.11466399e-02)
    return TheType(@eval ϑ -> ($(c_ν[1]) + ($(c_ν[2]) + $(c_ν[3])/ϑ)/ϑ)/ϑ)
end

# generating the original function
function Factory4()
    return TheType(@eval function(ϑ)
        c_ν = (1.99218000e-05, 3.29378459e-03, -4.11466399e-02)
        return (c_ν[1] + (c_ν[2] + c_ν[3]/ϑ)/ϑ)/ϑ
    end)
end

t1 = Factory1()
t2 = Factory2()
t3 = Factory3()
t4 = Factory4()

```

Using `@btime` calling `fun(92.95)` or `t1.f(92.95)`, I get 0.001ns (= nothing) for `fun` and around 35ns for all the others (with `-O3`). However, when I look at `@code_warntype` and `@code_llvm`, everything looks exactly the same, except for `t2.f` (which I expected since it is the only version accessing a captured variable).

Also, timing everything for one million evaluations yields the same result:

```julia
function the_loop()
    for i=1:1_000_000
        t1.f(92.95)
    end
end
the_loop()
t_el = @elapsed the_loop()
println("Time for 1 eval: $(t_el*1000)ns")

```

Since also 35ns is almost nothing; am I hunting ghosts here?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 15, 2019, 6:57am UTC](https://discourse.julialang.org/t/function-created-by-factory-function/23154/2 "2019-04-15T06:57:14Z")

</div>

> [@asprionj](#):
>
> The problem is the performance of the `::Function`

Use a concrete (parametric) type, eg

```julia
struct TheType{F <: Function}
    f::F
end

```

---

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [April 15, 2019, 7:58am UTC](https://discourse.julialang.org/t/function-created-by-factory-function/23154/3 "2019-04-15T07:58:02Z")

</div>

Thanks a lot for this very quick response! Found that out by myself just seconds ago, with help of the single answer to [this (old) post on SO](https://stackoverflow.com/questions/34841635/immutable-type-with-function-fields-in-julia). Do I need the `<: Function` for the speedup/type stability or is this just to restrict the type the constructor accepts?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 15, 2019, 8:13am UTC](https://discourse.julialang.org/t/function-created-by-factory-function/23154/4 "2019-04-15T08:13:59Z")

</div>

Just to restrict the types.
