Contiguous tuples of size 4

I’m trying to create a FixedArray4<Element> struct along the lines of FixedArray.swift in the standard library. I need this functionality because I’m implementing a JPEG codec, and the JPEG standard uses a lot of array variables of length 4 (eg, 4 quantization tables, 4 huffman tables, 4 component selectors, etc). However, the @_fixed_layout attributes don’t work on internal declarations when compiling a normal binary (as opposed to the standard library), and I obviously need the guarantee that the backing storage won’t get rearranged on the stack (regardless of whether the declared layout is respected at the module interface boundary). Any help on this would be appreciated, as I really don’t want to resort to switch statements in hot subscripts.

Tuples of one element type will always have contiguous layout (not counting padding), and a struct with a single element always has the same layout as that element. So your implementation is just

struct FixedArray4<Element> {
  var storage: (Element, Element, Element, Element)

and then whatever conveniences you want to add on top of that.

1 Like

but if I declare a local variable of type FixedArray4 won’t the compiler dismantle it for optimization like it does for any other struct?

That's true for absolutely everything. If the compiler notices you allocating an UnsafeMutablePointer, storing into it, and immediately freeing it, it's allowed to delete the store, for example.

The important point here is that while you have an address for the variable, it has to have its standard layout.

I did some actual testing, and… it seems there is absolutely no difference at all. If anything normal swift Arrays are a little faster if Element is a large struct. (The tuple-backed FixedArray is faster if Element is small, like an Int.) I have no explanation why this is the case.

./arraybenchmarks // lower is better
fixed size array of Ints, with pointer subscript: 263262
fixed size array of Ints, with switch case subscript: 281201
normal Swift array of Ints: 268217

fixed size array of large structs, with pointer subscript: 275872 
fixed size array of large structs, with switch subscript: 266557
normal Swift array of large structs: 266825 

The testing code is here.

1 Like