digitalmars.D - Arrays vs slices
- bearophile (27/38) Jun 09 2009 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- Steve Schveighoffer (9/12) Jun 10 2009 No, please no! Do I really need to carry around an integer that is goin...
- bearophile (6/12) Jun 11 2009 Strides aren't essential, but once in a while they are useful, I use the...
- Steven Schveighoffer (5/11) Jun 11 2009 The only time I use a "stride" is when I know I need a stride. That is,...
Once the language tells apart arrays and slices, the arrays may have a third field that represents the capacity, and the slices may have a third field that represents the stride (that defaults to 1). Python slices with strides specified:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]a = range(10) a[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]a[:][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]a[::][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]a[::1][0, 2, 4, 6, 8]a[::2][0, 3, 6, 9]a[::3][9, 8, 7, 6, 5, 4, 3, 2, 1, 0]a[::-1][9, 7, 5, 3, 1]a[::-2][10, 1, 20, 3, 30, 5, 40, 7, 50, 9] A simple example of stride usage, a true FFT (cmath contains functions that work on complex numbers): from cmath import exp, pi def fft(x): N = len(x) if N <= 1: return x e = fft(x[0 : : 2]) o = fft(x[1 : : 2]) return [e[k] + exp(-2j * pi / N * k) * o[k] for k in xrange(N // 2)] + \ [e[k] - exp(-2j * pi / N * k) * o[k] for k in xrange(N // 2)] t = fft([1.0] * 4 + [0.0] * 4) print t[len(t)//2 :], "\n", t[: len(t)//2] The output: [0j, (0.99999999999999989+0.41421356237309492j), 0j, (0.99999999999999967+2.4142135623730949j)] [(4+0j), (1-2.4142135623730949j), 0j, (1-0.41421356237309492j)] Bye, bearophilea[::2] = [10, 20, 30, 40, 50] a
Jun 09 2009
On Tue, 09 Jun 2009 16:22:39 -0400, bearophile wrote:Once the language tells apart arrays and slices, the arrays may have a third field that represents the capacity, and the slices may have a third field that represents the stride (that defaults to 1).No, please no! Do I really need to carry around an integer that is going to be unused 99.9% of the time (In my case, probably 100%)? I'd rather have a special type that has a stride. But, the capacity field is good. I would imagine that is a must for appendable arrays. Would be nice to specify an allocation strategy for arrays too, so we can avoid some of the issues being discussed about the GC allocating gigabytes for a 40MB array. -Steve
Jun 10 2009
Steve Schveighoffer:No, please no! Do I really need to carry around an integer that is going to be unused 99.9% of the time (In my case, probably 100%)? I'd rather have a special type that has a stride.Strides aren't essential, but once in a while they are useful, I use them now and then in Python. How can you tell that you don't need them so strongly? But I agree that passing 3-structs is slower than 2-structs (having a "slice with stride" type in some standard library can be enough).Would be nice to specify an allocation strategy for arrays too, so we can avoid some of the issues being discussed about the GC allocating gigabytes for a 40MB array.Just fixing the bug and putting there a sensible default seems more than enough to me. Variable allocation strategies are fine for library-defined arrays, but built-ins are better kept simple and flexible and efficient. Bye, bearophile
Jun 11 2009
bearophile Wrote:Steve Schveighoffer:The only time I use a "stride" is when I know I need a stride. That is, carrying the stride around with the slice is only useful if the code using it doesn't know it needs to be strided, and just lets the object tell it what values it needs. But if you know you want every other element, it's not that hard to construct a for-loop that does what you want. That method seems far more appealing to me and probably performs better. Especially in the 99% of cases you want to use a stride of 1, there is no runtime check. The cases where I want to use a function that operates on an array but stride the input (the only use case I see for stride to be builtin to an array) are non-existent in my code. -SteveNo, please no! Do I really need to carry around an integer that is going to be unused 99.9% of the time (In my case, probably 100%)? I'd rather have a special type that has a stride.Strides aren't essential, but once in a while they are useful, I use them now and then in Python. How can you tell that you don't need them so strongly?
Jun 11 2009