# Performance issues with constructors for arbitrary types

**URL:** <https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590>\
**Category:** General Usage\
**Created:** [June 1, 2020, 10:59pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590 "2020-06-01T22:59:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [June 1, 2020, 10:59pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590/1 "2020-06-01T22:59:12Z")

</div>

Hello all. I’ve been struggling now for a good while with a performance issue that seems it should be quite trivial to resolve, but so far, an elegant solution has eluded me.

So, I have an object `t::Table{T}` which lazily loads (from unstructured, untyped IO) the fields of an instance of `T`. I want to construct from this an instance of `T`. My thinking is that, if `T` is mutable, this should be a no-op.

I would _like_ to do this with

```julia
(t::Table{T})() where {T} = T((getproperty(t, n) for n ∈ fieldnames(T))...)

```

however, this performs rather badly:

```julia
julia> @btime $t()
  14.923 μs (93 allocations: 5.48 KiB)

```

On the other hand, if I do

```julia
function (t::Table{T})() where {T}
    m = T() # this is definitely wasting its time on defaults
    for s ∈ fieldnames(T)
        setfield!(m, s, getproperty(t, s))
    end
    m
end

```

I do somewhat better

```julia
julia> @btime $t()
  11.636 μs (69 allocations: 4.28 KiB)

```

which is a little surprising especially because I don’t even have an appropriate constructor for this (`T()` is definitely doing some unnecessary allocations).

I have often been confused about the performance consequences of splatting in the past. I have often been surprised with it not seeming to cost me anything, but in other cases like this, it’s seemingly disastrous.

So, what’s the best way to declare this constructor? Right now the best I could do would be to define a `T(undef)` that does as little as possible and then set the fields afterward.

---

<div class="post-metadata">

**Author:** ![benninkrs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benninkrs/32/3191_2.png) [@benninkrs](https://discourse.julialang.org/u/benninkrs)\
**Post date:** [June 1, 2020, 11:12pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590/2 "2020-06-01T23:12:39Z")

</div>

In my experience splatting is fast when the compiler can determine the number and type of arguments, but when it can’t you take a significant hit. I strongly suspect the return type of getproperty is not inferred.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [June 1, 2020, 11:14pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590/3 "2020-06-01T23:14:41Z")

</div>

Right, it’s not. Actually this is a somewhat separate issue I’ve been trying to deal with: I’d like to convince the compiler that `getproperty` should give types according to the fields of `T`, but the only way I can think of doing this so far is with some rather elaborate code generation that I’d like to avoid.

This still begs the question though, what’s the right way of doing this in this situation?

---

<div class="post-metadata">

**Author:** ![benninkrs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benninkrs/32/3191_2.png) [@benninkrs](https://discourse.julialang.org/u/benninkrs)\
**Post date:** [June 1, 2020, 11:21pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590/4 "2020-06-01T23:21:52Z")

</div>

Do you know ahead of time the type of object you’re trying to load?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [June 1, 2020, 11:24pm UTC](https://discourse.julialang.org/t/performance-issues-with-constructors-for-arbitrary-types/40590/5 "2020-06-01T23:24:11Z")

</div>

Yes, it would look something like `deserialize(T, io)`, but so far I’ve mostly failed to get the compiler to take advantage of the fact that the schema is actually known. The functions which fetch the individual fields are not type stable, because there’s basically no way of asserting the types of each field (again, without some fairly elaborate code generation).

I mean, I suppose it’s obvious to me by now that the only thing I can really do is define a constructor that just calls `new()` and fill in the fields after, it’s just a pretty unsatisfying result, because there’s no other reason it should have such a constructor (and because of the nature of the problem, if I override the default constructors I’ll need some more elaborate macros).
