Skip to content

Instantly share code, notes, and snippets.

@Veedrac
Created January 3, 2016 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Veedrac/64c21efb4a7399213b0d to your computer and use it in GitHub Desktop.
Save Veedrac/64c21efb4a7399213b0d to your computer and use it in GitHub Desktop.
/**
* This code uses std.experimental.ndslice to take the mean of the columns in
* a 2d 100x1000 array and creates a benchmark of that code.
*
* My mean running time is about 1.2 ms.
*
* If we compare this code to the Numpy equivalent,
*
* import numpy
* data = numpy.arange(100000, dtype="int32").reshape((100, 1000))
* means = numpy.mean(data, axis=0)
*
* and we benchmark the numpy.mean line using the following Python command,
*
* python -m timeit \
* -s 'import numpy; data = numpy.arange(100000, dtype="int32").reshape((100, 1000))' \
* 'means = numpy.mean(data, axis=0)'
*
* then we get a mean running time of about 65 µs. That means the Python version is about 20x
* as fast as the D version.
*
* D's slowness here is unexpected. Precomputing `means` as a `double` type does not fix this.
*
* If instead you do
*
* .map!(r => sum(r, 0L) / r.length) // D
* numpy.mean(data, dtype="uint64", axis=0) # Python
*
* I get about 35 µs and 85 µs instead, so D is roughly 2.4x as fast as the Python version.
*/
import std.range : iota;
import std.array : array;
import std.algorithm;
import std.datetime;
import std.conv : to;
import std.stdio;
import std.experimental.ndslice;
enum testCount = 10_000;
double[] means;
int[] data;
void f0() {
means = data
.sliced(100, 1000)
.transposed
.map!(r => sum(r, 0.0) / r.length)
.array;
}
void main() {
data = 100_000.iota.array;
auto r = benchmark!(f0)(testCount);
auto f0Result = to!Duration(r[0] / testCount);
f0Result.writeln;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment