The code isn't quite as terrible if compiled with optimizations on. I like your hypothesis elsewhere in the thread, that the optimization pass is probably removing unneeded array copying that hinder the performance of the debug build.
Semantically, an Array is an automatically resizing, reference-counted, copy-on-write, bounds-checking sequence of elements, none of which I want if I'm building a buffer for pixel values. So there is a significant mismatch between my desired use case and the characteristics of Array. I really do think there should be a fixed-size non-copy-on-write collection type at some point added to the language.
From an operational perspective, you're right, the analogy is quite leaky if you examine it closely.
Note that automatic resizing and reference counting won't hurt you in these cases. Bounds checking can, but eliminating bounds checks by proving that your accesses are always in-bounds at compile time is old hat by this point. Copy-on-write semantics are trickier to make fast, which is why I'm guessing they're the root cause here.
Semantically, an Array is an automatically resizing, reference-counted, copy-on-write, bounds-checking sequence of elements, none of which I want if I'm building a buffer for pixel values. So there is a significant mismatch between my desired use case and the characteristics of Array. I really do think there should be a fixed-size non-copy-on-write collection type at some point added to the language.
From an operational perspective, you're right, the analogy is quite leaky if you examine it closely.