Benchmarking mir.ndslice + lubeck against numpy and Julia
p.shkadzko
p.shkadzko at gmail.com
Sat Jan 11 21:54:13 UTC 2020
Today I decided to write a couple of benchmarks to compare D mir
with lubeck against Python numpy, then I also added Julia
snippets. The results appeared to be quite interesting.
Allocation and SVD of [5000 x 10] matrix:
+--------+--------------------+------------+
| lang | libs | time (sec) |
+--------+--------------------+------------+
| Python | numpy+scipy | 0.5 |
| Julia | LinearAlgebra | 0.0014 |
| D | mir.ndslice+lubeck | 0.6 |
+--------+--------------------+------------+
Allocation and SVD of [5000 x 100] matrix:
+--------+--------------------+------------+
| lang | libs | time (sec) |
+--------+--------------------+------------+
| Python | numpy+scipy | 4.5 |
| Julia | LinearAlgebra | 0.024 |
| D | mir.ndslice+lubeck | 5.2 |
+--------+--------------------+------------+
Allocation and SVD of [5000 x 1000] matrix:
+--------+--------------------+------------+
| lang | libs | time (sec) |
+--------+--------------------+------------+
| Python | numpy+scipy | 1.4 |
| Julia | LinearAlgebra | 1 |
| D | mir.ndslice+lubeck | 12.85 |
+--------+--------------------+------------+
Allocation and SVD of [500 x 10000] matrix:
+--------+--------------------+------------+
| lang | libs | time (sec) |
+--------+--------------------+------------+
| Python | numpy+scipy | 2.34 |
| Julia | LinearAlgebra | 1.1 |
| D | mir.ndslice+lubeck | 25 |
+--------+--------------------+------------+
Matrices allocation and dot product A [3000 x 3000] * B [3000 x
3000]
+--------+--------------------+------------+
| lang | libs | time (sec) |
+--------+--------------------+------------+
| Python | numpy+scipy | 0.62 |
| Julia | LinearAlgebra | 0.215 |
| D | mir.ndslice+lubeck | 1.5 |
+--------+--------------------+------------+
D lubeck's svd method it quite slow and gets even slower with
growth of the second dimension while scipy svd becomes
surprisingly faster. Dot product unfortunately is also
disappointing. I can only complement Julia on such amazing
results.
Below is the code I was using.
Allocation and SVD of [A x B] matrix:
Python
------
import numpy as np
from scipy.linalg import svd
import timeit
def svd_fun():
data = np.random.randint(0, 1024, 5000000).reshape((5000,
1000))
u, s, v = svd(data)
print(timeit.timeit(svd_fun, number=1))
Julia
-----
using LinearAlgebra
using BenchmarkTools
function svdFun()
a = rand([0, 1024], 5000, 1000)
res = svd(a)
end
@btime svdFun()
D mir.ndslice+lubeck
--------------------
/+dub.sdl:
dependency "mir" version="~>3.2.0"
dependency "lubeck" version="~>1.1.7"
libs "lapack" "openblas"
+/
import std.datetime;
import std.datetime.stopwatch : benchmark;
import std.stdio;
import std.random : Xorshift, unpredictableSeed, uniform;
import std.array: array;
import std.range: generate, take;
import mir.ndslice;
import mir.math.common : optmath;
import lubeck;
void svdFun()
{
Xorshift rnd;
rnd.seed(unpredictableSeed);
auto matrix = generate(() => uniform(0, 1024, rnd))
.take(5000_000)
.array
.sliced(5000, 1000);
auto svdResult = matrix.svd;
}
void main()
{
auto svdTime = benchmark!(svdFun)(1);
writeln(svdTime);
}
Matrices allocation and dot product A [3000 x 3000] * B [3000 x
3000]
Python
------
def dot_fun():
a = np.random.random(9000000).reshape((3000, 3000))
b = np.random.random(9000000).reshape((3000, 3000))
c = np.dot(a, b)
print(timeit.timeit(dot_fun, number=10)/10)
Julia
-----
function dotFun()
a = rand([0, 1.0], 3000, 3000)
b = rand([0, 1.0], 3000, 3000)
c = dot(a, b)
end
@btime dotFun()
D mir.ndslice+lubeck
--------------------
static @optmath auto rndMatrix(T)(const T maxN, in int dimA, in
int dimB) {
Xorshift rnd;
rnd.seed(unpredictableSeed);
const amount = dimA * dimB;
return generate(() => uniform(0, maxN, rnd))
.take(amount)
.array
.sliced(dimA, dimB);
}
static @optmath T fmuladd(T, Z)(const T a, Z z){
return a + z.a * z.b;
}
void dotFun() {
auto matrixA = rndMatrix!double(1.0, 3000, 3000);
auto matrixB = rndMatrix!double(1.0, 3000, 3000);
auto zipped = zip!true(matrixA, matrixB);
auto dot = reduce!fmuladd(0.0, zipped);
}
void main()
{
auto dotTime = benchmark!(dotFun)(1);
writeln(dotTime);
}
More information about the Digitalmars-d
mailing list