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