Questions about the slice operator
Jonathan M Davis
jmdavisProg at gmx.com
Tue Apr 3 19:11:55 PDT 2012
On Wednesday, April 04, 2012 03:29:03 ixid wrote:
> I understand the basic use to slice an array but what about these:
>
> foreach(i;0..5)
> dostuff;
>
> That works yet this does not:
>
> foreach(i;parallel(0..5))
> dostuff;
>
> Why not let this work? It'd seem like a natural way of writing a
> parallel loop. For some reason:
>
> foreach(i;[0,1,2,3,4])
> dostuff;
> This performs far more slowly than the first example and only as
> fast as it when parallelized with a ~150ms function for each
> iteration.
And what would it mean in the case of parallel(0 ..5)? Notice that
foreach(i; 0 .. 5)
and
foreach(i; [0, 1, 2. 3. 4]))
mean _completely different things. The first one doesn't involve arrays it all.
It gets lowered to something like
for(int i = 0; i < 5; ++i)
.. is _never_ used for generating an array. It's only ever used for indicating
a range of values. If you want to generate a range, then use std.range.iota.
.. wouldn't make sense in the contexts that you're describing. It would have
to generate something. And if 0 .. 5 generated [0, 1, 2, 3, 4] in the general
case, then
foreach(i; ident([0 .. 5])
would be just as inefficient as
foreach(i; [0, 1, 2, 3, 4, 5]))
even excluding the cost of ident (which presumably just returns the array).
foreach(i; 0 .. 5)
is more efficient only because it has _nothing_ to do with arrays. Generalizing
the syntax wouldn't help at all, and if it were generalized, it would arguably
have to be consistent in all of its uses, in which case
foreach(i; 0 .. 5)
would become identical to
foreach(i; [0, 1, 2, 3, 4])
and therefore less efficient. Generalizing .. just doesn't make sense.
> One final thought- why is the array function required to convert
> a lazy Result to an eager one? If you explicitly set something
> like int[] blah = lazything why not have it silently convert
> itself?
That would be an incredibly bad idea. Converting from a lazy range to an array
is expensive. You have to process the entire range and allocate memory for the
array that you're stuffing it in. Sometimes, you need to do that, but you
certainly don't want it to happen by accident. If such conversions were
implicit, you'd get hidden performance hits all over the place if you weren't
really careful. And in general, D isn't big on implicit conversions anyway.
They're useful in some cases, but they often causes bugs. So, D allows a lot
fewer implicit conversions than C++ does, and ranges follow that pattern.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list