# View and Slices: comparison of speed

#1

I measured the speed for mapping a function of several variables on `slices` and `views` of arrays.
The speed of slicing seems to be higher than views!
And using the macro form, `@view`, increases the speed compared to the explicit functional form, `view(...)` !
The size of allocations are the same for all three forms, but the number of allocations is considerably lower for the slicing.

Is there an explanation for this?

``````function secant(x1, x2, y1, y2)
s1 = (y2 - y1) / (x2 - x1)
return s1
end

N0 = 10^6;
xs = 1:N0;
ys = 2.5xs;

@time map(secant, xs[1:end-1], xs[2:end], ys[1:end-1], ys[2:end]);

# 0.022587 seconds (27 allocations: 7.631 MiB)

@time map(secant, @view(xs[1:end-1]), @view(xs[2:end]), @view(ys[1:end-1]), @view(ys[2:end]) );

# 0.035256 seconds (99 allocations: 7.634 MiB)

@time map(secant, view(xs, 1:endof(xs)-1), view(xs, 2:endof(xs)), view(ys, 1:endof(ys)-1), view(ys, 2:endof(ys)) );

# 0.062632 seconds (99 allocations: 7.634 MiB, 33.77% gc time)
``````

Times are measured on Intel Core i3 under Ubuntu 16 LTS.

#2

That’s because you’re not really allocating new slices in the first place. Both `xs` and `ys` look to be ranges – and slicing a range produces another range. Ranges are compact representations of vectors with evenly increasing values. Try it with `xs=collect(1:N0)` instead.

Even still, the speed of views isn’t always a win – that’s one reason why we decided not to make it the default.

#3

could you comment on the number of allocations in each case?

#4

Allocating a new range is about the same cost and size as allocating a view into a range. Try it with vectors instead of ranges and you’ll see a difference in memory allocated but the allocation count may be similar since we still cannot always eliminate allocating view objects (but a lot of work has been done on that).

#5

That’s just an artifact of doing your timing at global scope:

``````julia> fslices(xs, ys) = map(secant, xs[1:end-1], xs[2:end], ys[1:end-1], ys[2:end])

julia> fviews(xs, ys) = map(secant, @view(xs[1:end-1]), @view(xs[2:end]), @view(ys[1:end-1]), @view(ys[2:end]) )

julia> fslices(xs, ys); @time fslices(xs, ys);
0.024084 seconds (6 allocations: 7.630 MiB)

julia> fviews(xs, ys); @time fviews(xs, ys);
0.029539 seconds (6 allocations: 7.630 MiB)

julia> xs′ = collect(xs);
ys′ = collect(ys);

julia> fslices(xs′, ys′); @time fslices(xs′, ys′);
0.030760 seconds (18 allocations: 38.148 MiB)

julia> fviews(xs′, ys′); @time fviews(xs′, ys′);
0.027073 seconds (14 allocations: 7.630 MiB)
``````