# Static view

**URL:** <https://discourse.julialang.org/t/static-view/19836>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 20, 2019, 9:39am UTC](https://discourse.julialang.org/t/static-view/19836 "2019-01-20T09:39:48Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 20, 2019, 9:39am UTC](https://discourse.julialang.org/t/static-view/19836/1 "2019-01-20T09:39:49Z")

</div>

I am slicing up a `Vector{T}` to pieces of heterogeneous lengths, which are known at compile-time. Getting `StaticArray`s would help. Does the following (much simplified for the MWE) make sense?

```julia
using StaticArrays

struct SView{L}
    start::Int
end

function Base.view(x::Vector{T}, v::SView{L}) where {T,L}
    reinterpret(SVector{L,T}, view(x, v.start:(v.start + L - 1)))
end

x = collect(1:10)
v = SView{4}(3)
view(x, v)

```

Also, I wonder if it would be possible to make it faster, the `@code_warntype` output is type-stable but quite convoluted.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [January 20, 2019, 10:02am UTC](https://discourse.julialang.org/t/static-view/19836/2 "2019-01-20T10:02:33Z")

</div>

How about this, avoiding the view? 2ns instead of 16:

```julia
function Base.view(x::Vector{T}, v::SView{L}) where {T,L}
    SVector{L,T}(ntuple(i -> x[i+v.start-1], L))
end

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 20, 2019, 10:05am UTC](https://discourse.julialang.org/t/static-view/19836/3 "2019-01-20T10:05:08Z")

</div>

Excellent, this would also work for other `<: AbstractVector`.

For some reason I thought that just reinterpreting a contiguous piece of memory would be fastest, but maybe I am approaching this wrong.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [January 20, 2019, 10:53am UTC](https://discourse.julialang.org/t/static-view/19836/4 "2019-01-20T10:53:45Z")

</div>

What about loading SVectors directly from your vector?

```julia
using StaticArrays

struct SView{L}
    start::Int
end

function Base.view(x::Vector{T}, v::SView{L}) where {T,L}
    reinterpret(SVector{L,T}, view(x, v.start:(v.start + L - 1)))
end

x = collect(1:10)
v = SView{4}(3)
view(x, v)

function svload(x::Vector{T}, v::SView{L}) where {T,L}
    ptr_x = Base.unsafe_convert(Ptr{SVector{L,T}}, pointer(x))
    unsafe_load(ptr_x + (v.start-1) * sizeof(T))
end
svload(x, v)

```

For comparison,

```julia
julia> view(x, v)
1-element reinterpret(SArray{Tuple{4},Int64,1,4}, view(::Array{Int64,1}, 3:6)):
 [3, 4, 5, 6]

julia> svload(x, v)'
1×4 LinearAlgebra.Adjoint{Int64,SArray{Tuple{4},Int64,1,4}}:
 3 4 5 6

julia> @code_native svload(x, v)
	.text
; ┌ @ REPL[12]:2 within `svload'
; │┌ @ abstractarray.jl:882 within `pointer'
; ││┌ @ REPL[12]:2 within `unsafe_convert'
	movq	(%rsi), %rax
; │└└
; │ @ REPL[12]:3 within `svload'
; │┌ @ int.jl:52 within `-'
	movq	(%rdx), %rcx
; │└
; │┌ @ pointer.jl:105 within `unsafe_load' @ pointer.jl:105
	vmovups	-8(%rax,%rcx,8), %ymm0
; │└
	movq	%rdi, %rax
	vmovups	%ymm0, (%rdi)
	vzeroupper
	retq
	nopw	(%rax,%rax)
; └

```

You’d probably want to add an `@boundscheck` to svload. Right now it isn’t safe.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [January 20, 2019, 11:15am UTC](https://discourse.julialang.org/t/static-view/19836/5 "2019-01-20T11:15:46Z")

</div>

In order to get proper boundscheck elision, use

```julia
julia> function Base.view(x::Vector{T}, v::SView{L}) where {T,L}
          @boundscheck checkbounds(x, v.start:v.start+L)
          SVector{L,T}(ntuple(i -> (@inbounds x[i+v.start-1]), L))
       end
julia> iv(x,v)=@inbounds view(x,v)
julia> @code_native iv(x,v)
	.text
; Function iv {
	movq	(%rdx), %rax
	movq	(%rsi), %rcx
	vmovups	-8(%rcx,%rax,8), %ymm0
	vmovups	%ymm0, (%rdi)
	movq	%rdi, %rax
	vzeroupper
	retq
	nopw	(%rax,%rax)
;}
julia> view(x, SView{4}(9))
ERROR: BoundsError: attempt to access 10-element Array{Int64,1} at index [9:13]

```

Also note that proper vector loads are used. This is the idiom I’d recommend and use in my own code (in order to work around the current penalty for reinterprets between `Vector{<:SVector}` and `Matrix`). Apart from genericity, you don’t need to spend thought on GC visibility. E.g., does `svload` need a `GC.@preserve`? Probably yes, but I don’t want to think about it.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [January 20, 2019, 11:52am UTC](https://discourse.julialang.org/t/static-view/19836/6 "2019-01-20T11:52:32Z")

</div>

Nice, this is more honestly a view, while mine should probably be a method of `getindex`. They appear to be the same speed though, if both are without bounds checks.
