# Performance of dot operator on Nullables

**URL:** https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071
**Category:** Internals & Design
**Tags:** question
**Created:** [April 5, 2017, 5:01pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071 "2017-04-05T17:01:53Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)
#### Post date: [April 5, 2017, 5:01pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/1 "2017-04-05T17:01:53Z")

</div>

I was just comparing the performance of a handcoded lifted version of say addition for Nullables with the version that is in base now using the dot notation. My benchmark code looks like this:

```julia
a = Nullable(2)
b = Nullable(4)

@benchmark $a .+ $b

function my_addition{T<:Number}(a::Nullable{T}, b::Nullable{T})
    if isnull(a) || isnull(b)
        return Nullable{T}()
    else
        return Nullable(get(a)+get(b))
    end
end

@benchmark foo($a, $b)

```

Using the dot notation leads to performance that is about an order of magnitude worse than the hand coded version. Here are my benchmark results, first using the dot notation:

```julia
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 65.146 ns (0.00% GC)
  median time: 70.344 ns (0.00% GC)
  mean time: 75.946 ns (0.00% GC)
  maximum time: 311.660 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 987
  time tolerance: 5.00%
  memory tolerance: 1.00%

```

And for my hand coded version:

```julia
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 7.546 ns (0.00% GC)
  median time: 7.849 ns (0.00% GC)
  mean time: 8.439 ns (0.00% GC)
  maximum time: 34.414 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000
  time tolerance: 5.00%
  memory tolerance: 1.00%

```

Is there any hope that the dot version might become as fast as a hand coded version? Or is this a known limitation that can’t really be solved?

I was hoping that I could use the dot notation in [Query.jl](https://github.com/davidanthoff/Query.jl) to deal with `Nullable`s, but that won’t really work with this kind of performance characteristic…

PS: And yes, I’m aware of [https://github.com/JuliaLang/Juleps/pull/21](https://github.com/JuliaLang/Juleps/pull/21), but I couldn’t really get an answer to my (narrow) question here about the performance of the dot operation on `Nullable`s.  
PPS: CC @nalimilan, who probably just knows the answer 🙂

---

<div class="post-metadata">

### Author: ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)
#### Post date: [April 5, 2017, 7:03pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/2 "2017-04-05T19:03:26Z")

</div>

When [https://github.com/JuliaLang/julia/pull/16961](https://github.com/JuliaLang/julia/pull/16961) was merged, the dot syntax was as performant as the hand-written version (actually moreso, as it avoids a branch). Something must have happened in the meantime. Can you file an issue?

---

<div class="post-metadata">

### Author: ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)
#### Post date: [April 5, 2017, 7:46pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/3 "2017-04-05T19:46:14Z")

</div>

I looked into it and I believe it is a codegen regression/change that has caused this problem, but I can’t identify which one. I have a quick patch that will fix this regression by changing the Nullable broadcast code.

After the patch I get

```julia
julia> @benchmark Nullable(1) .+ Nullable(2)
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 1.338 ns (0.00% GC)
  median time: 1.357 ns (0.00% GC)
  mean time: 1.452 ns (0.00% GC)
  maximum time: 14.030 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000
  time tolerance: 5.00%
  memory tolerance: 1.00%

```

which I hope you’ll find more pleasant 😉.

* * *

The PR is taking slightly longer to finish than I’d like due to some stray segmentation faults and other concerns. I should have it up for review by the end of the day.

---

<div class="post-metadata">

### Author: ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)
#### Post date: [April 5, 2017, 11:22pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/4 "2017-04-05T23:22:15Z")

</div>

That looks fantastic!

Are there any caveats about using this for lifting in something like Query that I should know about? To me this looks as if it more or less solves the whole lifting debate we had, but I’m a bit worried that I’m overlooking something (because why did we even have [https://github.com/JuliaLang/Juleps/pull/21](https://github.com/JuliaLang/Juleps/pull/21) otherwise?).

---

<div class="post-metadata">

### Author: ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)
#### Post date: [April 5, 2017, 11:29pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/5 "2017-04-05T23:29:15Z")

</div>

In terms of this particular syntax and performance, I’d say there aren’t really any caveats. The unfortunate thing is that we don’t have a nice way to broadcast dot calls, i.e. it’s not easy to do `x ..+ y` if we have `Array{<:Nullable}`.

The Julep proposes a nicer and more flexible lower-level representation of `Nullable` than the existing one and the currently recommended option is not anticipated to really change the existing `broadcast` methods. (`Union{Some{T}, Null}`)

The other options that would change the semantics of dot-calls would be using `Union{T, Null}` and `Union{T, Null{T}}` to represent `Nullable{T}`, which are currently being actively discussed. However both these solutions are significantly more difficult changes than `Union{Some{T}, Null}`, so I believe that if the faster union types get into 1.0, we will start with that, and the `broadcast` methods will remain unchanged.

---

<div class="post-metadata">

### Author: ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)
#### Post date: [April 5, 2017, 11:44pm UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/6 "2017-04-05T23:44:36Z")

</div>

Thanks, that clarifies things a lot!

---

<div class="post-metadata">

### Author: ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)
#### Post date: [April 8, 2017, 8:41am UTC](https://discourse.julialang.org/t/performance-of-dot-operator-on-nullables/3071/7 "2017-04-08T08:41:01Z")

</div>

I should update that thanks to Jeff’s PR

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

this performance regression should be gone now. Thanks again for the report!
