A few range questions
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jan 5 14:34:52 PST 2016
On 01/05/2016 01:48 PM, Charles Smith wrote:
> On Tuesday, 5 January 2016 at 19:42:42 UTC, Ali Çehreli wrote:
>> // Now they get their own arrays:
>> auto benchmarks = benchmark!(() => algorithmSort(arr.dup),
>> () => countingSort(arr.dup))(1);
>>
>
> I'm not sure what this explicitly is doing... Are you defining an
> anonymous function? If so, that seems really useful.
Yes. Since benchmark() expects no-parameter functions, that's a useful
way of testing functions that take parameters.
However, I should have created the arrays before calling benchmark().
Otherwise, the timings include .dup as well:
auto asArr = arr.dup;
auto csArr = arr.dup;
auto benchmarks = benchmark!(() => algorithmSort(asArr),
() => countingSort(csArr))(10);
>> I think .joiner is what you're looking for.
> I was searching the terms `concat` and `flatten ` when I was
> looking for this.
Yep, I always start searching for 'flatten' and then remember joiner. :p
> That said, I don't think the example for `chain` should compile then.
That worked because chain() received just a single range (of ranges), in
which case it had no effect.
>> My results with -O -inline -noboundscheck:
>>
>> Algorithm's Sort: 76 ms, 910 μs, and 8 hnsecs
>> Counting Sort : 21 ms, 563 μs, and 9 hnsecs
> Awesome
I am amazed! :) countingSort() beats algorithmSort() almost always. :)
Here is the final version of the program with 10 million elements and 4
million values (array that are so large cannot be allocated on the stack
for me; so, I used new):
enum elementCount = 10_000_000;
enum valueCount = 4_000_000;
void main() {
import std.conv : to;
import std.datetime;
import std.random;
import std.stdio;
auto arr = new int[elementCount];
for(int i; i < arr.length; ++i)
arr[i] = uniform(0, valueCount);
auto asArr = arr.dup;
auto csArr = arr.dup;
// Now they get their own arrays:
auto benchmarks = benchmark!(() => algorithmSort(asArr),
() => countingSort(csArr))(10);
writeln("Algorithm's Sort: ", to!Duration(benchmarks[0]));
writeln("Counting Sort : ", to!Duration(benchmarks[1]));
}
auto algorithmSort(int[] arr) {
import std.algorithm : sort, sum;
arr.sort();
return arr.sum;
}
auto countingSort(int[] arr) {
import std.algorithm : count, map, joiner, sum, each;
import std.range : array, repeat, enumerate;
auto hist = new uint[valueCount];
arr.each!(a => ++hist[a]);
auto result = hist[].enumerate.map!(t => t[0].repeat(t[1])).joiner;
return result.sum;
}
Now they are comparable:
Algorithm's Sort: 3 secs, 881 ms, 146 μs, and 1 hnsec
Counting Sort : 3 secs, 990 ms, 315 μs, and 4 hnsecs
Ali
More information about the Digitalmars-d-learn
mailing list