# Optimization allowed in C++14, not done in Julia, but could it be done?

**URL:** <https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217>\
**Category:** Performance\
**Created:** [May 15, 2021, 11:20pm UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217 "2021-05-15T23:20:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 15, 2021, 11:20pm UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/1 "2021-05-15T23:20:13Z")

</div>

I tried something similar to here:

> **[If you declare a vector inside a for loop, will it get removed from the...](https://www.quora.com/If-you-declare-a-vector-inside-a-for-loop-will-it-get-removed-from-the-memory-after-every-iteration/answer/User-11956034714365873629)**
>
> Answer (1 of 7): This question is tagged with the programming language categories “C++”, “C” (which doesn’t have standard vectors), and “Java”, plus other tags that don’t quite seem compatible: You might want to clean that up.
> 
> I’ll add a few notes...

```julia
julia> function demo()
         for i in 0:9
           v = [1, 2, 3]
           push!(v, i)
           println(size(v))
         end
       end
demo (generic function with 1 method)

julia> @code_native demo()

```

In Julia v is allocated, but not in similar code in C++ (optimized away).

Could Julia also do that? It seems it could, and doesn’t need permission from a spec. While C++14 spec allows it, it’s not clear why it needs to be in the spec, since it’s “allowed” not “required”?

Does Julia exploit information about newly created object in any way (with garbage collection, you may not in general rely on no other pointers to them, but here you could)?

I also tried without the println.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [May 16, 2021, 3:14am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/2 "2021-05-16T03:14:55Z")

</div>

Did you try it with a static vector, which is probably the better comparison to that particular cpp example?

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [May 16, 2021, 4:23am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/3 "2021-05-16T04:23:17Z")

</div>

I think this cannot be done because of side effects. Pushing a value to a vector can result in out of memory error. Many things with side effects like error throwing can suppress some further simplifications.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [May 16, 2021, 4:47am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/4 "2021-05-16T04:47:09Z")

</div>

Yeah, not sure. Thought there was a chance since it would just be creating new tuples from each other but perhaps you are probably right

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [May 16, 2021, 5:00am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/5 "2021-05-16T05:00:58Z")

</div>

I was saying about regular vectors but not `SVector` but it is not direct comparison to allocated vectors.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [May 16, 2021, 9:16am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/6 "2021-05-16T09:16:50Z")

</div>

The way it currently works, this is unlikely to happen soon.

`Array` is actually not a “real” julia type/object. It is implemented by the C runtime, and mostly used via the foreign function interface. Relevant exceptions are `getindex`, `setindex!` and `arraysize`, which are special-cased by codegen.

In other words, llvm cannot peek into Array internals for optimizations.

More relevant than allocation, `push!` / array resizing is not special-cased either, which is why `push!` is so damn slow (cannot be inlined, ~10 cycles).

I think the most realistic way is to compile some subset of the runtime library into both machine-code and llvm bitcode ( `clang -fembed-bitcode` / `-lto-embed-bitcode` style), and use some variant of link-time-optimization when loading a dynamic library with bundled bitcode. The same applies to BigInt and string.

This is a quite general FFI problem:

Have some nice C / rust / fortran code, and try to use it from julia; this works super nice and convenient with OK perf via the current method (compile foreign code into dynamic lib, load lib, use foreign function call).

When you want to get rid of the remaining overhead, e.g. want some foreign functions inlined, then you need to embed bitcode into the dynamic library (by now super common and convenient on apple; not too hard to do on linux; no idea about windows; but fundamentally this can only work with llvm-based compilers, like clang, flang, rust, and won’t work with the likes of gcc, icc or msvc).

Then you need some ugly dance with `clang.jl` that I forgot the details of. I’d prefer if this was part of julia Core, just like loading of dynamic libs is; especially since embedded bitcode is becoming so prevalent in the apple world, and a future of ThinLTO dynamic libraries for JIT and debug purposes would be awesome.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [May 24, 2021, 2:54am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/7 "2021-05-24T02:54:36Z")

</div>

> I think this cannot be done because of side effects.

But why C++ can do that? Memory error doesn’t create too much problem in this case. Consider this Julia code:

```julia
function f(x)
    y = 1
    if x > 0
        y = 2
    else
       error()
    end
    return y
end

```

Julia(or llvm) actually finds out that this function can only return 2:

```julia
julia> @code_llvm debuginfo=:none f(1)
define i64 @julia_f_211(i64 signext %0) {
top:
  %1 = icmp slt i64 %0, 1
  br i1 %1, label %L6, label %L3

L3: ; preds = %top
  ret i64 2

L6: ; preds = %top
  %2 = call nonnull {}* @j_error_213()
  call void @llvm.trap()
  unreachable
}

```

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [May 24, 2021, 5:27am UTC](https://discourse.julialang.org/t/optimization-allowed-in-c-14-not-done-in-julia-but-could-it-be-done/61217/8 "2021-05-24T05:27:56Z")

</div>

> [@anon56330260](#):
>
> > I think this cannot be done because of side effects.
> 
> But why C++ can do that?

Because the standard explicitly says it can, see the C++14 section in [new expression - cppreference.com](https://en.cppreference.com/w/cpp/language/new#Allocation).
