I am in the process of porting over some Matlab code that implements the Vector Field Navigation approached outline in Goncalves et al. 2010 leveraging AD. The code is working properly, but I am confused why two seemingly equivalent implementations results in significantly different timings and # of allocations.

`VF_grad()`

, takes function gradients as its arguments, while `VF_func()`

takes the original function and then determines the gradients.

```
using ForwardDiff
using StaticArrays
using LinearAlgebra
using BenchmarkTools
α1(x::AbstractArray) = (x[1]/13.0).^2.0 .+ (x[2]/7.0).^2.0 .- 1.0
α2(x::AbstractArray) = x[3]
V(x::AbstractArray) = -sqrt(α1(x)^2.0 + α2(x)^2.0);
∇α1(x::AbstractArray) = ForwardDiff.gradient(α1,x)
∇α2(x::AbstractArray) = ForwardDiff.gradient(α2,x)
∇V(x::AbstractArray) = ForwardDiff.gradient(V,x);
function VF_grad(x::AbstractArray, ∇α1::Function, ∇α2::Function, ∇V::Function, G::Real=1.0, H::Real=1.0)
∇α1x = ∇α1(x)
∇α2x = ∇α2(x)
circ = ∇α1x × ∇α2x
converge = ∇V(x)
G*converge + H*circ
end;
function VF_func(x::AbstractArray, α1::Function, α2::Function, V::Function, G::Real=1.0, H::Real=1.0)
∇α1x = ForwardDiff.gradient(α1,x)
∇α2x = ForwardDiff.gradient(α2,x)
circ = ∇α1x × ∇α2x
converge = ForwardDiff.gradient(V,x)
G*converge + H*circ
end;
## Make Data
eval_array = [SVector(rand(3)...) for i ∈ 1:750];
```

```
@btime VF_func.($eval_array, α1, α2, V)
@btime VF_grad.($eval_array, ∇α1, ∇α2, ∇V);
259.922 μs (9004 allocations: 275.58 KiB)
53.775 μs (4 allocations: 17.77 KiB)
```

Can somebody explain this behavior to me? Both look to be type-stable.

For some reason this behavior seems connected to `×`

. Changing `circ = ∇α1x × ∇α2x`

to `circ = ∇α1x`

leads to

```
51.266 μs (4 allocations: 17.77 KiB)
51.253 μs (4 allocations: 17.77 KiB)
```

Also, if I use the original definition of `circ`

but modify my return to `G*converge + circ`

, i.e. no `H*`

I get

```
51.489 μs (4 allocations: 17.77 KiB)
51.497 μs (4 allocations: 17.77 KiB)
```