on Sun Apr 10 2016, Michel Fortin <michel.fortin-AT-michelf.ca> wrote:
> So if you take this into account, storing the comparator as part of > the stride makes the cost more predictable: not only there is one > branch less in `next()`, but you avoid evaluating the condition which > has an unknown cost: the `stride < 0` part. > > And ideally you should make sure the optimizer can replace the > indirect call with a direct call to the comparator. You do that by not > making the comparator choice dependent on a runtime value, hence why I > suggested having distinct "down" variants for the convenience > functions: `stride(from:downTo:by:)` and > `stride(from:downThrough:by:)` and `Range.strindingDown(by:)`. A few points: 1. There's a balance to be struck between making sure the optimizer can do a good job under *absolutely all circumstances*, and keeping the API surface area small and simple. That makes me somewhat reluctant to add “down” variants, if as I suspect the optimizer does well in the vast majority of cases without them. 2. Similarly, I view r.striding(by: x) as redundant with stride(from: x, to: y, by: z). I'd rather not have them both. 3. The fact that we're migrating C-style for loops to uses of stride, as noted in https://github.com/apple/swift/pull/2125, has convinced me that, sadly, we may need an answer that doesn't involve ranges. But maybe something like for x in loop(from: 0.1, while: { $0 < 10 }, next: { $0 + .2 }) is sufficient for this purpose. -- Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution