Hi Ron,
Okay, did you try just using one Array
? I'd be really surprised if the speedup you saw here wasn't due to eliminating two of the 3 allocations.
My next step was to hoist the allocation out of the call to
evaluate
.
Hoisting the Array might be a good idea too.
IIUC, program.stack
is effectively a global variable here. That's awful, but if you can get away with it, it might be your cleanest answer. But try to use an Array
rather than raw memory if you can. And if you can't use an Array
, there's always UnsafeRawBufferPointer
or Data
.
Are there best practices in Swift for when using Array introduces too much overhead?
Have you seen Array.withUnsafe
[Mutable
]BufferPointer
? That's always been enough for me to get speed, if I discover safety checks are slowing down my array code..
Will SE-0322 provide a better solution?
Quite possibly, if you really need to use unsafe memory, it would.
If you could post a reduced example that shows what you're doing and demonstrates that it's slow, I could see if there's a way to speed it up without resorting to unsafe code.
Further musingsā¦
Sadly, Swift doesn't expose an alloca-like facility. I found a post where @jrose claimed to have observed heap-to-stack optimization for non-escaping classes, which presumably should work for Array
just as well as ManagedBuffer
, but I can't reproduce it with either one.
You can use tuples to build a fixed-sized array on the stack, but as the article notes, there's no way to avoid an initialization cost.
If you're willing to mix C and Swift, maybe you should consider something like this: https://github.com/dabrahams/alloca-swift, which seems to work (though I haven't timed it). It's really inconvenient that you have to funnel all the data through a void*
, but maybe you can make something better out of it.