

A traditional Julia array of immutable objects is an array of structures. Fieldsof a given object are stored adjacent in memory. However, this often inhibitsSIMD optimizations. StructsOfArrays implements the classic structure of arraysoptimization. The contents of a given field for all objects is stored linearlyin memory, and different fields are stored in different arrays. This permitsSIMD optimizations in more cases and can also save a bit of memory if the objectcontains padding. It is especially useful for arrays of complex numbers.
You can construct a StructOfArrays directly:
using StructsOfArraysA=StructOfArrays(Complex128,10,10)
or by converting an AbstractArray:
A=convert(StructOfArrays,complex(randn(10),randn(10)))
Beyond that, there's not much to say. Assignment and indexing works as withother AbstractArray types. Indexing aStructOfArrays{T} yields an object oftypeT, and you can assign objects of typeT to a given index. The "magic"is in the optimizations that the alternative memory layout allows LLVM toperform.
While you can create a StructOfArrays of non-isbits immutables, this isprobably slower than an ordinary array, since a new object must be heapallocated every time the StructOfArrays is indexed. In practice, StructsOfArraysworks best withisbits immutables such asComplex{T}.
using StructsOfArraysregular=complex(randn(1000000),randn(1000000))soa=convert(StructOfArrays, regular)functionf(x, a) s=zero(eltype(x))@simdfor iin1:length(x)@inbounds s+= x[i]* aend sendusing Benchmarks@benchmarkf(regular,0.5+0.5im)@benchmarkf(soa,0.5+0.5im)
The time forf(regular, 0.5+0.5im) is:
Average elapsed time: 1.244 ms 95% CI for average: [1.183 ms, 1.305 ms]Minimum elapsed time: 1.177 ms
and forf(soa, 0.5+0.5im):
Average elapsed time: 832.198 μs 95% CI for average: [726.349 μs, 938.048 μs]Minimum elapsed time: 713.730 μs
In this case, StructsOfArrays are about 1.5x faster than ordinary arrays.Inspection of generated code demonstrates thatf(soa, a) uses SIMDinstructions, whilef(regular, a) does not.