c# - Performance of ILNumerics of simple math operations over vectors vs system array and Math.NET -
i doing studies on numerical algorithms in c#. therefore did experiments in search suitable math library .net. 1 thing evaluate objective functions, functions take vector input , returns vector output. compared implementations of same objective function in ilnumerics, system array , math.net. syntax of ilnumerics makes stand out because resembles of matlab , r lengthy mathematical formulas. however, discovered same number of evaluations, ilnumerics seems taking longer either system array of math.net. below code used compare. i'm not doing linear algebra here, purely applying math formulas on long vectors.
[test] public void testfunctioneval() { int numobj = 2; int m = 100000; func<double[], double[]> fun1 = (x) => { double[] z = new double[numobj]; z[0] = x[0]; double g = 1.0; (int = 1; < x.length; i++) g = g + 9.0 * x[i] / (m - 1); double h = 1.0 - math.sqrt(z[0] / g); z[1] = g * h; return z; }; func<ilarray<double>, ilarray<double>> fun2 = (x) => { ilarray<double> z = zeros(numobj); z[0] = x[0]; ilarray<double> g = 1.0 + 9.0 * sum(x[r(1, end)]) / (m - 1); ilarray<double> h = 1.0 - sqrt(z[0] / g); z[1] = g * h; return z; }; func<vector<double>, vector<double>> fun3 = (x) => { densevector z = densevector.create(numobj, (i) => 0); z[0] = x[0]; double g = 1.0 + 9.0*(x.subvector(1, x.count - 1) / (m - 1)).sum(); double h = 1.0 - math.sqrt(z[0] / g); z[1] = g * h; return z; }; int n = 1000; ilarray<double> xs = rand(n, m); ilist<double[]> xraw = new list<double[]>(); (int = 0; < n; i++) { double[] row = xs[i, full].toarray(); xraw.add(row); } densematrix xden = densematrix.ofrows(n, m, xraw); stopwatch watch = new stopwatch(); watch.start(); (int = 0; < n; i++) { ilarray<double> ret = fun1(xraw[i]); } watch.stop(); log.infoformat("system array took {0} seconds.", watch.elapsed.totalseconds); watch.reset(); watch.start(); (int = 0; < n; i++) { ilarray<double> ret = fun2(xs[i, full]); } watch.stop(); log.infoformat("ilnumerics took {0} seconds.", watch.elapsed.totalseconds); watch.reset(); watch.start(); (int = 0; < n; i++) { var ret = fun3(xden.row(i)); } watch.stop(); log.infoformat("math.net took {0} seconds.", watch.elapsed.totalseconds); }
unfortunately, test shows ilnumerics taking long simple.
315 | system array took 0.7117623 seconds. 323 | ilnumerics took 14.5100766 seconds. 330 | math.net took 5.3917536 seconds.
i liked way made code mathematical formulas. however, taking many more times time taken system array or math.net evaluate functions such above means have choose other alternatives instead of ilnumerics though lead longer , harder interpret functions.
am using ilnumerics in wrong way? or design slower in kind of scenarios. maybe i'm not using suitable purpose. can explain?
ilnumerics 3.2.2.0 , math.net.numerics 2.6.1.30 used in test.
yes, missing general performance testing rules. , comparison not fair:
for ilnumerics implementation, create lot of temporaries of considerable size. disadvantageous in comparison other implementations, create long vector once , operations in 'inner loop'. inner loop faster - expense of less expressive syntax , more programming effort. if need performance, can use x.getarraysforread() , x.getarrayforwrite() use underlying system.array directly. gets options system.array test...
you include lot of subarrays creation (and new memory allocations) in tests ilnumerics not included in other tests. example, derive subarrays big test data matrix inside measurement loop.
why not design tests way: create 1 large matrix every test individually. use mathnet matrices mathnet test, system.array matrix system.array test , ilarray ilnumerics. in every iteration, extract corresponding row , give corresponding function.
do not forget follow ilnumerics function rules: http://ilnumerics.net/generalrules.html , run test release build without debugger attached. usual, leave out time needed first iteration.
depending on system (and automatic parallelization options brings) ilnumerics might still slower. in case, consider follow further optimization options of ilnumerics or optimize inner loop resorting system.array.
@edit: 1 more note: aware of fact, kind of misleading such micro tests without doing usefull. results might not suitable derive expectations performance of final application from. 1 example: if iterate on large arrays solely system.array long time, end spending time in gc instead of computing numbers. have carefull, not newly allocate storage makes code more clumsy.
ilnumerics - if used correctly - prevents spending time in gc reusing memory automatically. also, parallelizes algorithm internally (even if using vectors not demanding enough parallelization in example).
Comments
Post a Comment