Is there a need to use the “.” for vector math when adding and multiplying?

```
a = [1 2 3]
b = [3 4 5]
# Which is better for performance? They both do the same thing.
c = 1/2 * a + b
d = 1/2 .* a .+ b
```

Is there a need to use the “.” for vector math when adding and multiplying?

```
a = [1 2 3]
b = [3 4 5]
# Which is better for performance? They both do the same thing.
c = 1/2 * a + b
d = 1/2 .* a .+ b
```

1 Like

The second should be about 2x faster. The second will compile to roughly

```
d=Vector{Float64}(undef, length(a))
for i in eachindex(a,b)
d[i] = .5*a[i]+b[i]
end
```

while the first will use 2 loops and allocate an intermediate vector.

If you don’t want to have ot use lots of dots, you could write this as

`@. d = 1/2 * a+b`

7 Likes

(or `d = @. 1/2 * a+b`

if `d`

is not preallocated)

5 Likes

Awesome. Thank

And here I am after using Julia for quite a while now, not knowing that `1/2 .* a`

is better than `1/2*a`

… Always room for improvement.

Note that this only matters when `a`

is a collection, and the `.`

can be fused with another operation. `1/2 * a`

will be just as fast as `1/2 .* a`

. The only difference is if you add another operation that broadcasting can fuse.

3 Likes

You’re not saying that this:

` c = 1/2 * a .+ b`

will be as fast as this:

` c = 1/2 .* a .+ b`

are you?

No.

Basically in any expression with dots, you can imagine all dots on the same level being fused together into one element-wise function going over all involved iterables just once. It’s a syntax transformation basically. You can do the same if you write `broadcast(f, iterables...)`

but that’s not nice syntax

1 Like

When is `(*)(x::Real, y::AbstractArray)`

not equivalent to its broadcasted version? Shouldn’t `1/2 * a .+ b`

fuse automatically? I believe there are always cases where this shouldn’t be done, but for the standard number types this should be okay, no?

The problem is that broadcasting happens on the syntax level. When you write `1/2 *a .+b`

it gets lowered to

```
temp1 = 1/2 *a
return broadcast(+, a, b)
```

The reason broadcasting needs to be explicit is that lowering happens before type inference, so decisions about broadcast fusing can’t depend on types.

1 Like

Thanks! I guess I read that already at the time, but forgot about it again.

1 Like