# What is StrideArrays.jl

**URL:** <https://discourse.julialang.org/t/what-is-stridearrays-jl/97146>\
**Category:** Performance\
**Tags:** arrays\
**Created:** [April 6, 2023, 1:39am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146 "2023-04-06T01:39:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [April 6, 2023, 1:39am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/1 "2023-04-06T01:39:50Z")

</div>

It’s an odd question to ask, but I see StrideArrays.jl being used in a lot of extremely performance critical code, but meanwhile the documentation of the project… leaves a lot to be desired.

So: what is StrideArrays.jl? How does it differ to other array types like in Base or StaticArrays? And where is it advantageous to use it?

---

<div class="post-metadata">

**Author:** ![AMJ](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amj/32/214096_2.png) [@AMJ](https://discourse.julialang.org/u/AMJ)\
**Post date:** [April 6, 2023, 6:15am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/2 "2023-04-06T06:15:53Z")

</div>

CC StrideArrays’ package maintainer @Elrod

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 6, 2023, 7:30am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/3 "2023-04-06T07:30:38Z")

</div>

Extending the question: is there a “what for” summary table for users in disarray, regarding all existing array packages:

```julia
StructArrays
StaticArrays
StrideArrays
LazyArrays
AxisArrays
OffsetArrays
BlockArrays
InfiniteArrays
FillArrays
IndirectArrays
MappedArrays
HybridArrays
GetindexArrays
ArrayViews
ArraysOfArrays
UnsafeArrays
StructsOfArrays
ShiftedArrays
RangeArrays
MetadataArrays
AbstractArraysOfArrays
UnalignedVectors
# etc.

```

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [April 6, 2023, 9:33am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/4 "2023-04-06T09:33:50Z")

</div>

In most cases, the GitHub package description and README should help, I guess?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 6, 2023, 9:51am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/5 "2023-04-06T09:51:09Z")

</div>

I think a summary table on the main JuliaArrays page would be extremely helpful:

> **[JuliaArrays](https://github.com/JuliaArrays)**
>
> Custom array types (and utilities for building array types) for Julia - JuliaArrays

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [April 6, 2023, 10:02am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/6 "2023-04-06T10:02:20Z")

</div>

Perhaps JuliaArrays can have a documentation website that describes the packages?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [April 6, 2023, 11:34am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/7 "2023-04-06T11:34:47Z")

</div>

> **[Stride of an array](https://en.wikipedia.org/wiki/Stride_of_an_array)**
>
> In computer programming, the stride of an array (also referred to as increment, pitch or step size) is the number of locations in memory between beginnings of successive array elements, measured in bytes or in units of the size of the array's elements. The stride cannot be smaller than the element size but can be larger, indicating extra space between elements.
> An array with stride of exactly the same size as the size of each of its elements is contiguous in memory. Such arrays are sometimes sai...

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [April 7, 2023, 1:48am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/8 "2023-04-07T01:48:13Z")

</div>

No I know what a stride or step is, thanks.

That’s not what the package StrideArrays.jl are about - at least not with respect to their performance and statically defined size. And it’s those details I’m asking about here.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [April 7, 2023, 2:47am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/9 "2023-04-07T02:47:46Z")

</div>

Chris obviously has the last word on this, but I see StrideArrays as somewhere between a “prelude” (in the Haskell/Rust sense of the word) library and a playground for hyper-optimizing array operations on CPU. That’s part of why it doesn’t feel like there’s a coherent API boundary or documentation story: it’s more of a conglomerate of things to make particular downstream workloads its dependencies and users require faster rather than a standalone library (though technically it is one) with a clear mission statement (other than making particular stuff go fast).

To be clear, none of this is meant as a slight against StrideArrays.jl. I think it’s more of a reflection of the diversity of different package types we have in this ecosystem.

---

<div class="post-metadata">

**Author:** ![j-fu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j-fu/32/11373_2.png) [@j-fu](https://discourse.julialang.org/u/j-fu)\
**Post date:** [April 7, 2023, 12:27pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/10 "2023-04-07T12:27:51Z")

</div>

I discovered this package while searching for a possibility to allocate mutable arrays on the stack which can be also passed to functions without (heap) allocations. So I plan to try this out in certain situations as as a replacement of StaticArrays. StaticArrays.SArray is not mutable, and StaticArrays.MArray appears to be (heap) allocating in many situations.

I however find the name of the package quite misleading. StackArrays.jl IMHO would describe more precisely what it does.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [April 7, 2023, 3:33pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/11 "2023-04-07T15:33:06Z")

</div>

But it does more than just that, so it should also be called SIMDArrays.jl. I might be wrong, but I believe you can have heap-allocated StrideArrays as well? Thus my point about it being more of a conglomerate than your average package.

---

<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:** [April 7, 2023, 8:35pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/12 "2023-04-07T20:35:17Z")

</div>

`StrideArrays` will often be heap allocated, too.  
They should often SIMD. So should regular `Array` or `StaticArrays`, but `StrideArrays` should SIMD more reliably.

> [@j-fu](#):
>
> I discovered this package while searching for a possibility to allocate mutable arrays on the stack which can be also passed to functions without (heap) allocations.

It should support that with the `@gc_preserve` macro, but escape analysis in the Julia compiler should eventually enable this in more situations for other types, like `MArray`.

The key is to `GC.@preserve` the memory, and then replace arrays with `PtrArray`s, views that don’t own the memory but otherwise act the same.

So what are `StrideArrays.jl`’s goals and vision?  
StrideArrays’s goal is to support strided use cases as well as it can.  
I believes code should return the correct answer as quickly as possible with as little effort as possible from the user.

So array operations should SIMD as much as possible, thus StrideArrays does its best to do this.  
We should try and minimize the amount of allocations needed, so StrideArrays tries to do its best there.

StrideArrays also prefers a flexible flat representation, over nested layer types. The transpose of a `StrideArray` isn’t a `Transpose{T,<:StrideArray}`, but another `StrideArray`. Same for a `view` – you get a `StrideArray` not a `SubArray`, `permutedims` returning a `StrideArrays` view rather than a `PermutedDimsArray` wrapper, etc.

In short, this is what `StrideArray`s is actually about:  
A flexible representation that can represent all of `Array`, `Transpose`, `SubArray`, `PermutedDimsArray`, `StaticArrays`, `HybridArrays`, etc, and nested combinations thereof.  
No need for extra implementations, or introspection to peal off layers.

What `StrideArrays` is about is this representation. This strided representation.  
Hence, the name.

Other features like SIMD and helping to cut down heap allocations are because these sorts of optimizations simply make sense to do, and are easy enough – or are simpler with one flat representation to deal with.

But the package was/is an experimental playground, so maybe that’s why the documentation and API boundary don’t have a good story?  
PRs are always welcome to improve any deficiencies.

I’d also hope it is for the most part relatively easy to use. `Polyester.jl` turns arrays into `StrideArrays` under the hood, and I don’t think many people notice (other than that their code suddenly allocates a lot less vs `Threads.@threads`) or complain, which says something about it working reasonably well as a drop in replacement.

The biggest difference vs regular arrays is that slicing makes views by default, not copies.  
Also, you should probably start Julia with `--check-bounds=yes` while developing.

---

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [April 7, 2023, 9:14pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/13 "2023-04-07T21:14:34Z")

</div>

> [@Elrod](#):
>
> The biggest difference vs regular arrays is that slicing makes views by default, not copies.

Do you mean expressions like `A[1:k]` does not create copies? This seems very useful. How is this compared to `@views`?

---

<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:** [April 8, 2023, 4:19am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/14 "2023-04-08T04:19:23Z")

</div>

```julia
julia> using StrideArrays, Test

julia> using Test

julia> a = StrideArray(zeros(77));

julia> b = a[10:20];

julia> b[4] = 7;

julia> @test a[13] == 7 # 0-based indexing > 1-based
Test Passed

julia> @test typeof(a) === typeof(b)
Test Passed

```

The difference vs `@views` is that it should be better at preserving the type of the original array, meaning that hopefully it won’t cause as much unnecessary code specialization.

With `Vector{Float64}`, the view would have type `SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}`, meaning type inference through llvm code gen all need to run again for no real reason.

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 8, 2023, 7:35am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/15 "2023-04-08T07:35:14Z")

</div>

For me the `typeof` test doesn’t pass, what could be the reason?  
It’s `StrideArray{Float64, 1, (1,), Tuple{Int64}, Tuple{Nothing}, ...}` for `a` and `StrideArray{Float64, 1, (1,), Tuple{Int64}, Tuple{Int64}, ...}` for `b`.

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [April 8, 2023, 9:46am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/16 "2023-04-08T09:46:26Z")

</div>

Thanks @Elrod for your description.

Regarding the ‘more likely to SIMD’ aspect - is this a factor of the size of the array being part of the type system?

As for the possibility of sometimes being stack allocated - how does it do that?

---

<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:** [April 8, 2023, 11:52am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/17 "2023-04-08T11:52:35Z")

</div>

Try updating to the latest version.

---

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [April 8, 2023, 1:34pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/18 "2023-04-08T13:34:51Z")

</div>

Thank you!

---

<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:** [April 8, 2023, 3:36pm UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/19 "2023-04-08T15:36:10Z")

</div>

> [@torrance](#):
>
> Regarding the ‘more likely to SIMD’ aspect - is this a factor of the size of the array being part of the type system?

No, it’s that it uses `LoopVectorization.jl` for things like broadcasting.

> [@torrance](#):
>
> As for the possibility of sometimes being stack allocated - how does it do that?

A bit hacky/manually. You need to declare statically sized arrays (or, soon, [small arrays](https://github.com/JuliaSIMD/StrideArraysCore.jl/issues/38)).  
You’d need to `@gc_preserve` them when passing through function boundaries.

Once the Julia compiler enables escape analysis for this, the `@gc_preserve` will no longer be necessary (and `StaticArrays.MArray` will work, too).

Note that `StrideArrays.@gc_preserve` will also work on `StaticArrays.MArray`, but you may as well use a `StaticStrideArray` instead.

---

<div class="post-metadata">

**Author:** ![dankelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dankelley/32/33539_2.png) [@dankelley](https://discourse.julialang.org/u/dankelley)\
**Post date:** [April 11, 2023, 9:44am UTC](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146/20 "2023-04-11T09:44:10Z")

</div>

I had a look at the github site and did not see answers to the questions posed here, particularly the key “what is” question. I don’t think this makes the package much different from other Julia packages, though.

Narrow documentation can limit language acceptance and thus sustainability. Julia is not without competition. On one side we have compiled languages such as Fortran, C++, etc., for which many excellent textbooks are available. And on the interactive side we have Python, R, etc., for which detailed and precise documentation tends to be closely coupled with the code.

I realize that Julia is still fairly young, and that many of its users are busy solving their own problems. Perhaps patterns will change. I hope so, because I think Julia holds some promise.

[Next page](https://discourse.julialang.org/t/what-is-stridearrays-jl/97146.md?page=2)
