Too complicated code for generating a random string?

monarch_dodra monarchdodra at gmail.com
Sat Feb 23 13:57:41 PST 2013


On Saturday, 23 February 2013 at 20:21:18 UTC, jerro wrote:
>> BTW, I think the clearest remains my generator proposal:
>> string randomString =
>>    fastGenerator!(() => letters[uniform(0, $)]).take(9).array;
>
> If the goal was to replace iota(n).map, it may be better to 
> just have something like:
>
>     generate!(() => letters[uniform(0, $)])(n).array

Arguably, the goal is to actually replace "repeat+map". I view 
the fact that iota not being infinite as a drawback. And even if 
you do want a bound to the length of your range, I believe it 
should be the "top" step in your types, as opposed to the 
"bottom" step. Eg:

iota(n).map!(_ => letters[uniform(0, $)]).array;
vs
repeat(0).map!(_ => letters[uniform(0, $)]).take(n).array;

*Personally*, I prefer the logic behind the repeat+map+take, over 
iota+map's. It might actually even be faster. It is slightly more 
verbose though :/

------
Another advantage "generate" would have over repeat+map is if you 
want to pass an actual named impure function (as opposed to 
lambda):

iota(0, n).map(_ => fun());
or
repeat(0).map(_ => fun()).take(n);
vs
fastGenerate!fun().take(n);

Here, the generate would be much more "idiomatic", and also 
probably easier on the compile (function vs lamba: easier 
inlining, as you mention below).

> But of course, your fastGenerator is more general. I personally 
> don't often have a need to generate an infinite range in this 
> way, but other people may.
>
>> Any chance you could tell me how it fares in your bench?
>
> I used this code:
>
> auto tmp = FastGenerator!(() => letters[uniform(0, 
> $)])().take(n).array;
>
> When I build it with GDC, it performs about the same as the 
> code that uses iota and map. When I build it with DMD it's 
> about 10% slower than the code that uses iota and map. It seems 
> that DMD fails to inline the lambda in this case.
>
> By the way, this is not a very good benchmark for ranges 
> because most of the time is spent generating random numbers.

Another thing I'd like to re-bring up (which I've partially 
implemented already), was bearophile's pass/tee suggestion:
http://forum.dlang.org/thread/zkioveywsgxiovzvdypq@forum.dlang.org

It's those little functions that don't seem like much at first, 
but that really add up to a language's expressiveness (IMO).


More information about the Digitalmars-d mailing list