# Am I using DiffResults.jl correctly?

**URL:** https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894
**Category:** Performance
**Tags:** diffresults, forwarddiff
**Created:** [March 12, 2020, 5:59pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894 "2020-03-12T17:59:28Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)
#### Post date: [March 12, 2020, 5:59pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/1 "2020-03-12T17:59:28Z")

</div>

I’m trying to [compute Jacobian and function values simultaneously using ForwardDiff.jl](https://discourse.julialang.org/t/a-way-to-obtain-the-value-and-derivatives-with-forwarddiff/22862). A simple MWE example is

```julia
using StaticArrays
using ForwardDiff
using DiffResults
using BenchmarkTools

f(x) = SVector((@. x[1]*x[2]), x[1]+x[2])
df(x) = ForwardDiff.jacobian(f,x)
df_diffres(x) = ForwardDiff.jacobian!(DiffResults.JacobianResult(x),f,x)

```

If I benchmark each routine, the evaluation of `f` and `df` are both similar cost. However, evaluating `df_diffres` takes significantly longer than evaluating both the function and Jacobian.

```julia
julia> x = SVector(1,2);
julia> @btime f($x)
  0.039 ns (0 allocations: 0 bytes)
julia> @btime df($x)
  0.039 ns (0 allocations: 0 bytes)
julia> @btime df_diffres($x)
  1.214 μs (14 allocations: 608 bytes)

```

Am I using DiffResults.jl incorrectly, or is there a way to reduce runtimes and allocations?

---

<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: [March 12, 2020, 7:19pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/2 "2020-03-12T19:19:29Z")

</div>

> [@jlchan](#):
>
> Am I using DiffResults.jl incorrectly, or is there a way to reduce runtimes and allocations?

Even with DiffResults you should be caching your config.

---

<div class="post-metadata">

### Author: ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)
#### Post date: [March 12, 2020, 7:25pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/3 "2020-03-12T19:25:02Z")

</div>

I tried that previously, but took it off b/c it was slower.

```julia
x = SVector(1,2)
cfg = ForwardDiff.JacobianConfig(f,x)
df_diffres(x) = ForwardDiff.jacobian!(DiffResults.JacobianResult(x),f,x,cfg)

```

gave a timing of `1.401 μs (16 allocations: 736 bytes)` for `df_diffres(x)`.

---

<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: [March 12, 2020, 7:32pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/4 "2020-03-12T19:32:50Z")

</div>

What if you use floating point numbers? Derivatives of integers is somewhat weird…

But I see what your issue is. If you’re using DiffRules with static vectors, of course it needs to allocate it when it stores it. It really only makes sense to define temporary storage with things that would use such storage (i.e. arrays)

---

<div class="post-metadata">

### Author: ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)
#### Post date: [March 12, 2020, 7:38pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/5 "2020-03-12T19:38:33Z")

</div>

Thanks for the tip. If I use `x = SVector(1.0,2.0)`, the timings change slightly but the ratios are about the same.

```julia
  24.150 ns (1 allocation: 32 bytes) # timing for f
  23.441 ns (1 allocation: 48 bytes) # timing for Jacobian
  161.444 ns (6 allocations: 176 bytes) # timing with DiffResults

```

On the allocation - that makes sense. Guess I got lucky - this setup is pretty representative of my use case, where a function (with a small number of inputs/outputs) is evaluated at many states using AD.

---

<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: [March 12, 2020, 8:00pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/6 "2020-03-12T20:00:55Z")

</div>

If everything is small enough for static vectors, then ignore DiffResults and configs. Those are for larger systems.

---

<div class="post-metadata">

### Author: ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)
#### Post date: [March 12, 2020, 8:09pm UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/7 "2020-03-12T20:09:13Z")

</div>

Ah, thanks! So if I’m understanding correctly - I should expect computing Jacobian and function values simultaneously using ForwardDiff.jl/DiffResults.jl to be faster than computing them separately, but only for a large enough number of inputs/outputs?

---

<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: [March 14, 2020, 5:06am UTC](https://discourse.julialang.org/t/am-i-using-diffresults-jl-correctly/35894/8 "2020-03-14T05:06:41Z")

</div>

> [@jlchan](#):
>
> I should expect computing Jacobian and function values simultaneously using ForwardDiff.jl/DiffResults.jl to be faster than computing them separately, but only for a large enough number of inputs/outputs?

It always computes it simultaneously: forward-mode AD cannot not do it simultaneously. However, it’s whether it’s stored in an intermediate for having the DiffRules interface: if it’s static vectors, putting it in a mutable type will currently require that it gets heap allocated, which is not great right now. However, that limitation should be lifted in v1.5 IIRC.
