The speed of Array vs. Hash element access is partially addressed by commit c10792f8. Before this commit, each Array element access via .at_pos($pos) resulted in an expensive call to self.exists($pos) for each access, whereas Hash element accesses via .at_key($key) were able to use nqp::existskey() directly. This patch uses nqp::existspos() to hotpath the detection of existing elements and avoids calls to self.exists($pos) when the Array is already fully reified.
For the benchmark given in RT #111848, this resulted in a ~25% speedup for array element accesses, and brings it to within 5% of Hash element access times. (At present Array element accesses still have more overhead at the PIR level than Hash element accesses due to laziness considerations and boundary checks. I'm still looking into the "two layers of nextiter" part; I agree it's somewhat surprising but I'm not convinced it's suboptimal within the current context of how we handle/store constant lists. For the array assignment Rakudo has to do iteration at some point in order to bring the elements into the "top-level" items part; it's simply choosing to do it at the time of Array element access instead of at the point of the assignment. Given that the ticket refers to "suboptimality", it's hard to know when it should be closed. If masak++ or someone else feels that this reply adequately addresses the issues for now, I'm fine with it being resolved now, or if we want to leave it open pending further discussion/resolution of the "two nextiter layer" issue, I'm fine with that also. Pm