# Fantastic progress in master branch!

**URL:** https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868
**Category:** Internals & Design
**Created:** [November 3, 2017, 8:39pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868 "2017-11-03T20:39:36Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [November 3, 2017, 8:39pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/1 "2017-11-03T20:39:36Z")

</div>

I’ve recently switched to the v0.7 master branch from v0.6 for the development of a computation-heavy package I’m making, and I am _very_ impressed! The transition was really easy. I essentially had to adapt the way I was using `CartesianRange`, which has now a different syntax, but the rest was all really smooth. But more importantly, I have been blown away by the efficiency gains. Even though the master branch is heavily in flux still, there must have happened something cool in the internals, because critical (fully type-stable) parts of my package that were doing like 54 k allocations for certain test benchmarks in v0.6 have magically gone down to 117 allocations in v0.7! Of course the performance has gone up at the same time. There are some instabilities and segfaults too, of course, but that’s to be expected. Overall I’m very excited about v0.7.

It would be great to know exactly what kind of wizardry is going on in the master branch, and what further progress to expect before 1.0, but I would probably not fully understand. I hear words like linear IR, but I’m afraid I lack the background to really get what it is about.

In any case I would like to enthusiastically congratulate the core developers for their _amazing_ work. I imagine it must be quite stressful at the moment with the upcoming 1.0 release, so receive some big cheers from Spain, your efforts are much appreciated!

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [November 3, 2017, 9:00pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/2 "2017-11-03T21:00:32Z")

</div>

IMO, the amazing wizardry which could just blow everything away hasn’t even merged yet:

[https://github.com/JuliaLang/julia/pull/24362](https://github.com/JuliaLang/julia/pull/24362)

though one of the big deals merged yesterday:

[https://github.com/JuliaLang/julia/pull/22194](https://github.com/JuliaLang/julia/pull/22194)

---

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [November 3, 2017, 9:29pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/3 "2017-11-03T21:29:49Z")

</div>

I have been watching the NamedTuples development for a long time, so I was very happy to see this merge. Hopefully it will soon enable fast keywords, that would be huge!

Could you point us to any thread explaining what the IPO thing is about?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [November 3, 2017, 9:43pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/4 "2017-11-03T21:43:44Z")

</div>

> [@pablosanjose](#):
>
> Could you point us to any thread explaining what the IPO thing is about?

The examples from here are the kind that would benefit from it:

> <https://github.com/JuliaLang/julia/issues/24011>
>
> It seems like in a lot of cases one wants to set a bunch of options. The options… are usually set by constants from the user, and they can easily affect type-stability. A simple example is \`qrfact\`. In these cases the current standard is to have the API be \`qrfact(A,Val{true})\`. But it seems like if you have \`qrfact(A,true)\`, Julia could in theory propagate the literal here. If the second argument is a constant in a function, then that could also happen at compilation time.
> 
> But you might not always want that because that could be too coarse of a compilation setup, so instead it might be nice to have an opt-in for that:
> 
> \`\`\`julia
> qrfact(A,pivot::Bool\[Infer\]=false)
> \`\`\`
> 
> or something like that to tell it to compile literals separately. Then APIs like \`qrfact(A,true)\` would allow optional arguments to change in a type-unstable way but keep type-stability when users are hardcoding the argument choice. When keyword dispatch is thing, it would be nice to allow this with keyword arguments as well.

The basic idea is that if you hardcode some constant, like

```julia
qr(A,true)

```

then that `true` could be propagated and compilation can take it into account. This would allow one to have “not type-stable functions” with switches by booleans, yet compilation would know how to make it type-stable by pushing the constants all the way through. This kind of thing can also make branches disappear and other optimizations just by using more information at compilation time.

Julia currently optimizes constants within a function. If you do:

```julia
a = false 
if !a
  # do stuff
end

```

it’ll compile away that branch if `a` isn’t used anywhere else. And in some cases this is already special cased, like for tuples `a[1]` can be type-stable even when the tuple is heterogeneous (when indexing with a literal instead of a variable).

Inter-procedural constant propogation means that in general functions can push constants into the other functions inside of them, and optimize the whole chain together. An example of this would be if you hardcode a call by symbol in a NamedTuple:

```julia
data[:this_column]

```

There’s a `getindex` function on `symbol` that needs to be called to convert that symbol into an index `data[i]`. Well if you have this constant propogation, the compiler can find out that `data[:this_column]` always turns into `data[i]`, and thus replace the symbols with the index (i.e. replace the constant with the constant result of using that constant in a function) at compilation time to make it faster. That’s seems to be the main impetus that’s pushing it right now:

> <https://github.com/JuliaLang/julia/issues/24441>
>
> I had hoped that indexing a named tuple (#22194) with a \`Symbol\` would be a type…-inferrable operation. I'm guessing that a tfunc or whatever, like for \`Tuple\`, may be needed here.
> 
> \`\`\`
> \_
> \_ \_ \_(\_)\_ | A fresh approach to technical computing
> (\_) | (\_) (\_) | Documentation: https://docs.julialang.org
> \_ \_ \_| |\_ \_\_ \_ | Type "?help" for help.
> | | | | | | |/ \_\` | |
> | | |\_| | | | (\_| | | Version 0.7.0-DEV.2400 (2017-11-02 03:12 UTC)
> \_/ |\\\_\_'\_|\_|\_|\\\_\_'\_| | ajf/empty/5fa163f (fork: 1 commits, 0 days)
> |\_\_/ | x86\_64-linux-gnu
> 
> julia\> nt = (a=1, b=2.0)
> (a = 1, b = 2.0)
> 
> julia\> f(x) = x\[:a\]
> f (generic function with 1 method)
> 
> julia\> @code\_warntype f(nt)
> Variables:
> x::NamedTuple{(:a, :b),Tuple{Int64,Float64}}
> 
> Body:
> begin
> return (Base.getfield)(x::NamedTuple{(:a, :b),Tuple{Int64,Float64}}, :a)::Union{Float64, Int64}
> end::Union{Float64, Int64}
> \`\`\`

tl;dr:

This plus the faster keyword arguments / NamedTuple change means you can have a crap ton of options, and if the user hardcodes in the options:

```julia
sol = solve(prob,Tsit5(),save_everystep=false,save_first=false, ...)

```

then Julia will compile a specific version of the function for that set of options and optimize on those choices. DifferentialEquations.jl has a few options, so I am quite excited to see this.

---

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [November 3, 2017, 9:54pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/5 "2017-11-03T21:54:58Z")

</div>

Thanks a lot! That begins to make sense. I assume it only applies to hard coded constants, not to user inputs?

So if someone does

```julia
function foo(a::AbstractArray{Bool})
  a[1] ? 1 : 2
end

```

and then calls `foo([true, false])`, will constant propagation allow to elide the `?` check altogether?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [November 3, 2017, 9:56pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/6 "2017-11-03T21:56:35Z")

</div>

> [@pablosanjose](#):
>
> and then calls foo([true, false]), will constant propagation allow to elide the ? check altogether?

if it’s written like that, i.e. a literal, then it can be propagated, and my understanding of the PR is that it will propagate it.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [November 4, 2017, 1:50pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/7 "2017-11-04T13:50:00Z")

</div>

I suspect a lot of the performance improvement had come from a change that @keno made plus follow up work by @yuyichao to take advantage of that change to improve performance. The original change made it possible to defer figuring out where objects need to be “rooted” so that garbage collection knows that an object cannot be safely freed until much later in the optimization process (during LLVM optimization), at which point it’s much easier to recognize cases where rooting isn’t actually needed at all, thereby allowing it to be avoided entirely. That, by itself doesn’t speed things up that much, but it opens the door for a lot of big improvements which Yichao has been taking good advantage of in a series of PRs. I believe the change may also be key to enabling @jameson’s PR above. I’ve said it before but it bears repeating: we’ve barely scratched the surface of the kinds of optimizations that we can do in Julia.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [November 4, 2017, 2:06pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/8 "2017-11-04T14:06:07Z")

</div>

> [@StefanKarpinski](#):
>
> we’ve barely scratched the surface of the kinds of optimizations that we can do in Julia.

This is so exciting!!! Amazing work people.

---

<div class="post-metadata">

### Author: ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)
#### Post date: [November 4, 2017, 4:59pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/9 "2017-11-04T16:59:01Z")

</div>

The microbenchmarks improve from 1.09 to 1.05 in geometric mean relative to C, going from 0.6.0 to 0.7.0-DEV. Depending on how you look at it, either it’s a mere 4% improvement, or it’s cutting the overhead over C by a factor of two!

Those numbers are constant to three digits on repeated runs on an unloaded machine.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [November 4, 2017, 5:24pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/10 "2017-11-04T17:24:56Z")

</div>

Thats pretty amazing. 4% doesn’t sound like a lot until you think about how fast this is converging to C speeds. If the claims that we’ve barely even scratched the surface of Julia’s optimization potential then perhaps its not too pie in the sky to imagine a future where we blow past C.

By the way, how is Julia compared to Go these days?

---

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [November 4, 2017, 5:25pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/11 "2017-11-04T17:25:21Z")

</div>

I find it _mindblowing_ that, being already so damn close to C, you have still “barely scratched the surface” of possible optimisations. Julia is already so smart! At this rate we will not even need to care about type-stability in the future, ha!

I really hope that many more people would start seeing the potential here, and begin investing in Julia… As a language I’m not sure its getting all the attention it deserves yet, at least among my colleagues in physics. Everybody is just doing Python and Matlab wherever I look!

---

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [November 4, 2017, 5:29pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/12 "2017-11-04T17:29:24Z")

</div>

@Mason, this thread is pretty cool

> [@Benchmark for latest julia?](https://discourse.julialang.org/t/benchmark-for-latest-julia/5991/53):
>
> I posted this PR a few days back. It gets test/perf/micro running again on julia-0.7.0. It’s a few Makefile changes for libraries that have moved in the julia source tree since 0.4.0. [https://github.com/JuliaLang/julia/pull/23922](https://github.com/JuliaLang/julia/pull/23922) A few things/decisions remain before producing new benchmark data for publication: Getting Fortran to call BLAS. I tried @Ralph_Smith’s suggestion above but got utterly horrific rand\_mat\_mul results (~100 times slower). I need to double-check that I linked to the …

It has updated the benchmarks of Julia against other languages. The big surprise for me, and some other people, has been SciLua, which apparently has a really sophisticated JIT compiler… It appears to be about as fast as Julia at the moment… without Julia scratching the surface 😃

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [November 4, 2017, 5:38pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/13 "2017-11-04T17:38:48Z")

</div>

@pablosanjose

> I really hope that many more people would start seeing the potential here, and begin investing in Julia… As a language I’m not sure its getting all the attention it deserves yet, at least among my colleagues in physics. Everybody is just doing Python and Matlab wherever I look!

Hopefully once 1.0 is out, people will have less reasons to be skeptical and be more open to moving over to Julia. There’s huge potential here, especially for physicists! I’m doing an exact diagonalization of the Hubbard model in Julia right now and its a treat.

> It has updated the benchmarks of Julia against other languages.

I’ve read that thread but theres still no Go benchmarks as far as I can tell.

> The big surprise for me, and some other people, has been SciLua, which apparently has a really sophisticated JIT compiler

Yeah that really surprised me too! The past few years really seem to be a bit of a JIT renaissance. Or maybe I’m just only paying attention now 😛

---

<div class="post-metadata">

### Author: ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)
#### Post date: [November 4, 2017, 7:07pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/14 "2017-11-04T19:07:13Z")

</div>

@Mason Go is back and the results are up on [https://julialang.org/](https://julialang.org/) and [Julia Micro-Benchmarks](https://julialang.org/benchmarks/) . Go comes in at about 1.5 on the geometric mean. The discussion about the benchmarks updates gradually shifted from Discourse to GitHub. For what it’s worth the geometric means for all languages are

```julia
cputime	lang
1.000	C
1.054 Julia 0.7.0 [EDIT: originally reported as 1.045]
1.093	Julia 0.6.0
1.109	LuaJIT
1.496	Fortran
1.511	Go
2.745	Java
3.448	JavaScript
12.790	Matlab
14.121	Mathematica
16.610	Python
70.955	R
575.269	Octave

```

That’s merging the 0.7.0 result into the list from 0.6.0 and perhaps misremembering the last digit. Three digits are significant, and caveat that these numbers and rankings depend on the choice of benchmarks in the suite.

[EDIT: I did indeed misremember the digits for julia-0.7.0. The correct geoemetric mean is 1.054]

---

<div class="post-metadata">

### Author: ![waldyrious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/waldyrious/32/80_2.png) [@waldyrious](https://discourse.julialang.org/u/waldyrious)
#### Post date: [November 5, 2017, 10:49am UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/15 "2017-11-05T10:49:32Z")

</div>

Wouldn’t it make sense to add a row at the bottom of the benchmarks table with the geometric mean of each column? That would help getting a better sense of the overall data present in the table.

Also, color-coding the entries red or green (for \>1.0 or \<1.0 of C) would help in this regard. I can send a PR adding these changes if there’s agreement.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [November 5, 2017, 11:13am UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/16 "2017-11-05T11:13:16Z")

</div>

For what it’s worth, I think those are good suggestions.

---

<div class="post-metadata">

### Author: ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)
#### Post date: [November 5, 2017, 1:11pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/17 "2017-11-05T13:11:35Z")

</div>

Putting the geometric mean at the bottom of the table is a great idea. I haven’t done it myself because the html table is produced by `test/perf/micro/bin/table.pl`, and I am perl-less. BTW, Stefan Karpinsky suggested rewriting that code in Julia so such changes would be easier for the Julia community. I haven’t had time for that yet.

Another fix that needs doing is printing `--` for missing data rather than 0.0. There is one missing datapoint: `print_to_file` for JavaScript.

My feeling is that red/green color coding might be a bit much, visually. But it’s worth a try.

@waldyrious a PR on these would be great!

{EDIT: but getting a bit off-topic. Let’s continue this elsewhere, like [https://github.com/JuliaLang/julialang.github.com/issues](https://github.com/JuliaLang/julialang.github.com/issues)]

---

<div class="post-metadata">

### Author: ![waldyrious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/waldyrious/32/80_2.png) [@waldyrious](https://discourse.julialang.org/u/waldyrious)
#### Post date: [November 5, 2017, 5:12pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/18 "2017-11-05T17:12:55Z")

</div>

> [@John\_Gibson](#):
>
> I haven’t done it myself because the html table is produced by test/perf/micro/bin/table.pl, and I am perl-less

Ah, I didn’t realize that. Alas, I too am perl-less…

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [November 5, 2017, 6:08pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/19 "2017-11-05T18:08:38Z")

</div>

You mean Perl-free? 😉

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [November 6, 2017, 3:42pm UTC](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868/20 "2017-11-06T15:42:00Z")

</div>

I suppose if no one else gets around to it, I’ll port it myself since it seems that no one else around here has much Perl knowledge.

[Next page](https://discourse.julialang.org/t/fantastic-progress-in-master-branch/6868.md?page=2)
