# Intermediate results (dereferencing, CSE, ..) - when to avoid?

**URL:** <https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024>\
**Category:** Performance\
**Created:** [August 8, 2021, 3:48pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024 "2021-08-08T15:48:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 8, 2021, 3:48pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/1 "2021-08-08T15:48:45Z")

</div>

A habit tells me to eliminate common subexpressions and to create intermediate variables.  
On the other hand, Julia’s performance is often judged by its allocations and so seems to suggest avoiding intermediate variables…

Take

```julia
    for ff = 1:nc
        write(io, UInt8(length(String(fieldnames(typeof(first(v)))[ff]))))
        write(io, String(fieldnames(typeof(first(v)))[ff]))
        ser(io, getfield.(v, fieldnames(typeof(first(v)))[ff]))
    end

```

vs.

```julia
for ff = 1:nc
    fieldName = fieldnames(typeof(first(v)))[ff]
    write(io, UInt8(length(String(fieldName))))
    write(io, String(fieldName))
    ser(io, getfield.(v, fieldName))
end

```

vs.

```julia
fieldNames = fieldnames(typeof(first(v)))
for ff = 1:nc
    write(io, UInt8(length(String(fieldNames[ff]))))
    write(io, String(fieldNames[ff]))
    ser(io, getfield.(v, fieldNames[ff]))
end

```

Is it reasonable to assume a threshold like _the effort for 3x calculation justifies intermediate storage_?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 8, 2021, 4:37pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/2 "2021-08-08T16:37:05Z")

</div>

Now you are just creating the intermediate storage _three times_, so it’s less readable, requires more calculation, _and_ more allocations.

In this case definitely create the intermediate.

Sometimes the compiler will eliminate CSEs automatically, but you can’t necessarily rely on that.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 8, 2021, 4:52pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/3 "2021-08-08T16:52:54Z")

</div>

> [@Bardo](#):
>
> seems to suggest avoiding intermediate variables…

I think there’s some misconception here. The intermediate is still allocated, even if you don’t assign a name to it. The object

```julia
fieldnames(typeof(first(v)))

```

is created and allocated, not naming it doesn’t help, it will just be assigned some internal label instead.

In cases where the intermediate is just some value, that does not need to be heap allocated, the allocations don’t matter either way, and you can create temporary variables to your heart’s content. But if the intermediate is an array, for example, then you get a real, and possibly expensive allocation over and over.

So in your case it’s not a trade-off, it’s just worse in every way to not assign the intermediate.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 8, 2021, 4:54pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/4 "2021-08-08T16:54:30Z")

</div>

Thx for the comment, clearer now!  
The heap is probably needed for larger intermediate results, so version 3 should be the preferred one?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 8, 2021, 5:10pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/5 "2021-08-08T17:10:41Z")

</div>

Version 3 looks best. Now, after checking, I see that `fieldnames` returns a tuple and not an array, which means that allocations isn’t necessarily a problem here.

But, as I mentioned, it’s not a trade-off the way you were thinking. Either the allocations don’t matter, so you can create an intermediate without cost, or the allocations _do_ matter, in which case you _should_ create an intermediate variable if you are using it repeatedly.

There are cases where _not_ creating an intermediate can be beneficial, but that is if you can work directly on the original object and avoid allocation completely. But this is unrelated to whether you assign a name to it or not.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 8, 2021, 5:50pm UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/6 "2021-08-08T17:50:40Z")

</div>

Or maybe this is cleaner

```julia
for name in fieldnames(typeof(first(v)))
    write(io, UInt8(length(String(name))))
    write(io, String(name))
    ser(io, getfield.(v, name))
end

```

It does the same thing, but `for val in iter` is normally nicer than `for i in 1:length(iter)` plus indexing.

(You actually do conversion from symbol to string twice, but it’s no big deal).

---

<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:** [August 10, 2021, 10:05am UTC](https://discourse.julialang.org/t/intermediate-results-dereferencing-cse-when-to-avoid/66024/7 "2021-08-10T10:05:04Z")

</div>

> [@DNF](#):
>
> Either the allocations don’t matter, so you can create an intermediate without cost, or the allocations _do_ matter, in which case you _should_ create an intermediate variable if you are using it repeatedly.

To expand on this: because of [referential transparency](https://en.wikipedia.org/wiki/Referential_transparency),

```julia
f(g(x))

```

and

```julia
y = g(x)
f(y)

```

are equivalent in Julia. The language does not care, `y` is merely a label for the programmer.
