# Zygote custom adjoint has surprising performance effects

**URL:** <https://discourse.julialang.org/t/zygote-custom-adjoint-has-surprising-performance-effects/36972>\
**Category:** Machine Learning\
**Tags:** question\
**Created:** [April 3, 2020, 3:26pm UTC](https://discourse.julialang.org/t/zygote-custom-adjoint-has-surprising-performance-effects/36972 "2020-04-03T15:26:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)\
**Post date:** [April 3, 2020, 3:26pm UTC](https://discourse.julialang.org/t/zygote-custom-adjoint-has-surprising-performance-effects/36972/1 "2020-04-03T15:26:03Z")

</div>

I am experimenting with custom adjoints in Zygote. In the following code, I defined an adjoint for the function `gauss`. Surprisingly, benchmarking `gradient` on `gauss` and a “wrapper” closure `f` around `gauss` shows that the gradient of `f` is 3-4 times faster than that of `gauss`. Before defining the custom adjoint, the two gradients have the same speed. After the definition, `f`’s gradient is 50% faster than before, while `gauss`’s gradient is 2 times slower.

Why does this happen, and how can I get optimal performance with custom adjoints consistently?

```julia
using Zygote
using BenchmarkTools

function gauss(x, μ, σ)
    y = (x-μ)/σ
    exp(-y^2/2) / (sqrt(2π)*σ)
end

using Zygote: @adjoint
@adjoint function gauss(x, μ, σ) 
    y = (x-μ)/σ
    e = exp(-y^2/2) / (sqrt(2π)*σ)
    function back(Δ)
        ey = e*y/σ # could pool e*Δ too
        (-ey * Δ, ey * Δ, e*(1 - y^2)/σ * Δ)
    end
    return e, back
end

x = randn()
μ = randn()
σ = exp(randn())
f(x, μ, σ) = gauss(x, μ, σ)
@btime gradient(f, $x, $μ, $σ)
@btime gradient(gauss, $x, $μ, $σ) # 3-4 times slower

```
