# Composing a constructor causes tons of allocations

**URL:** <https://discourse.julialang.org/t/composing-a-constructor-causes-tons-of-allocations/35405>\
**Category:** Performance\
**Created:** [March 2, 2020, 1:58pm UTC](https://discourse.julialang.org/t/composing-a-constructor-causes-tons-of-allocations/35405 "2020-03-02T13:58:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 2, 2020, 1:58pm UTC](https://discourse.julialang.org/t/composing-a-constructor-causes-tons-of-allocations/35405/1 "2020-03-02T13:58:38Z")

</div>

I’m trying to build a pipeline of transformations and noticed this weird behavior when I plugged a `Point2f0` constructor into the pipeline. I’ve removed the rest of the test pipeline and replaced it with the identity function to create the MWE.

```julia
using GeometryTypes

f_bad = Point2f0 ∘ identity
f_good = (x -> Point2f0(x)) ∘ identity

ps = rand(Point2{Float64}, 1_000_000)

```

```julia
julia> @btime f_bad.($ps)
102.237 ms (2999498 allocations: 68.66 MiB)

```

```julia
julia> @btime f_good.($ps)
1.304 ms (5 allocations: 7.63 MiB)

```

Can anybody help me to understand the cause?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 2, 2020, 5:27pm UTC](https://discourse.julialang.org/t/composing-a-constructor-causes-tons-of-allocations/35405/2 "2020-03-02T17:27:26Z")

</div>

That’s interesting–it looks like the closure that is built by the `\circ` operator ends up capturing `f` (the first function) as a field of the abstract type `DataType`:

```julia
julia> @code_warntype f_bad(ps[1])
Variables
  #self#::Base.var"#56#57"{DataType,typeof(identity)}
  x::Tuple{Point{2,Float64}}

Body::Any
1 ─ %1 = Core.getfield(#self#, :f)::DataType
│ %2 = Core.getfield(#self#, :g)::Core.Compiler.Const(identity, false)
│ %3 = Core._apply(%2, x)::Point{2,Float64}
│ %4 = (%1)(%3)::Any
└── return %4

```

and that makes the result of the composed function un-inferrable.

We can reproduce the issue without using `\circ` like so:

```julia
julia> function wrap(t)
         x -> t(x)
       end
wrap (generic function with 1 method)

julia> wrapped_point = wrap(Point2f0)
#14 (generic function with 1 method)

julia> @code_warntype wrapped_point(ps[1])
Variables
  #self#::var"#14#15"{DataType}
  x::Point{2,Float64}

Body::Any
1 ─ %1 = Core.getfield(#self#, :t)::DataType
│ %2 = (%1)(x)::Any
└── return %2

```

Seems like it would be worth opening an issue at [Issues · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues) , since this seems like a general issue with the way types are captured by closures.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [March 2, 2020, 8:14pm UTC](https://discourse.julialang.org/t/composing-a-constructor-causes-tons-of-allocations/35405/3 "2020-03-02T20:14:12Z")

</div>

There is:

[https://github.com/JuliaLang/julia/issues/23618](https://github.com/JuliaLang/julia/issues/23618)
