A few range questions
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jan 5 11:42:42 PST 2016
On 01/05/2016 10:47 AM, Charles Smith wrote:
> auto result = 1_000.iota.map!(a => a.repeat(count(arr[],
> a))).chain.array;
You are traversing the array per index value (1000 times), which can be
done once up front:
enum elementCount = 1_000_000;
enum valueCount = 1000;
void main() {
import std.conv : to;
import std.datetime;
import std.random;
import std.stdio;
int[elementCount] arr;
for(int i; i < arr.length; ++i)
arr[i] = uniform(0, valueCount);
// Now they get their own arrays:
auto benchmarks = benchmark!(() => algorithmSort(arr.dup),
() => countingSort(arr.dup))(1);
writeln("Algorithm's Sort: ", to!Duration(benchmarks[0]));
writeln("Counting Sort : ", to!Duration(benchmarks[1]));
}
auto algorithmSort(int[] arr) {
import std.algorithm : sort, sum;
auto result = sort(arr[]);
return result.sum;
}
auto countingSort(int[] arr) {
import std.algorithm : count, map, joiner, sum, each;
import std.range : array, repeat, enumerate;
uint[valueCount] hist;
arr.each!(a => ++hist[a]);
auto result = hist[].enumerate.map!(t => t[0].repeat(t[1])).joiner;
// To make sure that we consume the lazy range:
return result.sum;
}
> 2. I noticed that result within `countingSort` is an array of arrays. I
> thought `chain` would concat them... did I miss something obvious?
I think .joiner is what you're looking for.
> 3. It's kind of hard to compare performance because of (1), but is there
> a better way to do this?
I changed the code to pass each function a different array.
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
Ali
More information about the Digitalmars-d-learn
mailing list