mirror of
https://github.com/josdejong/mathjs.git
synced 2025-12-08 19:46:04 +00:00
122 lines
5.9 KiB
JavaScript
122 lines
5.9 KiB
JavaScript
/**
|
|
* Benchmark
|
|
*
|
|
* Compare performance of basic matrix operations of a number of math libraries.
|
|
*
|
|
* These are some rough benchmarks to get an idea of the performance of math.js
|
|
* compared to other JavaScript libraries and to Octave (C++). They only give an
|
|
* _indication_ of the order of magnitude difference meant to see were math.js
|
|
* has room for improvements, it's not a fully fletched benchmark suite.
|
|
*/
|
|
|
|
import { Bench } from 'tinybench'
|
|
import det from 'ndarray-determinant'
|
|
import gemm from 'ndarray-gemm'
|
|
import ops from 'ndarray-ops'
|
|
import pack from 'ndarray-pack'
|
|
import numeric from 'numericjs'
|
|
import sylvester from 'sylvester'
|
|
import eig from 'eigen'
|
|
import zeros from 'zeros'
|
|
import { all, create } from '../../lib/esm/index.js'
|
|
import { formatTaskResult } from './utils/formatTaskResult.js'
|
|
|
|
const bench = new Bench({ time: 10, iterations: 100 })
|
|
const math = create(all)
|
|
|
|
// fiedler matrix 25 x 25
|
|
const fiedler = [
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
|
|
[1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
|
|
[2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
|
|
[3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
|
|
[4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
|
|
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
|
|
[6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],
|
|
[7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
|
|
[8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
|
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
|
|
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
|
|
[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
|
[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
|
[14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
|
[16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8],
|
|
[17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7],
|
|
[18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6],
|
|
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5],
|
|
[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4],
|
|
[21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3],
|
|
[22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2],
|
|
[23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1],
|
|
[24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
|
];
|
|
|
|
(async function () {
|
|
// mathjs
|
|
(function () {
|
|
const A = math.matrix(fiedler, 'dense', 'number')
|
|
|
|
bench.add('matrix operations mathjs (number) A+A', function () { return math.add(A, A) })
|
|
bench.add('matrix operations mathjs (number) A*A', function () { return math.multiply(A, A) })
|
|
bench.add('matrix operations mathjs (number) A\'', function () { return math.transpose(A) })
|
|
bench.add('matrix operations mathjs (number) det(A)', function () { return math.det(A) })
|
|
})();
|
|
|
|
// mathjs
|
|
(function () {
|
|
const A = math.matrix(fiedler)
|
|
|
|
bench.add('matrix operations mathjs (generic) A+A', function () { return math.add(A, A) })
|
|
bench.add('matrix operations mathjs (generic) A*A', function () { return math.multiply(A, A) })
|
|
bench.add('matrix operations mathjs (generic) A\'', function () { return math.transpose(A) })
|
|
bench.add('matrix operations mathjs (generic) det(A)', function () { return math.det(A) })
|
|
})();
|
|
|
|
// sylvester
|
|
(function () {
|
|
const A = sylvester.Matrix.create(fiedler)
|
|
|
|
bench.add('matrix operations sylvester A+A', function () { return A.add(A) })
|
|
bench.add('matrix operations sylvester A*A', function () { return A.multiply(A) })
|
|
bench.add('matrix operations sylvester A\'', function () { return A.transpose() })
|
|
bench.add('matrix operations sylvester det(A)', function () { return A.det() })
|
|
})();
|
|
|
|
// numericjs
|
|
(function () {
|
|
const A = fiedler
|
|
|
|
bench.add('matrix operations numericjs A+A', function () { return numeric.add(A, A) })
|
|
bench.add('matrix operations numericjs A*A', function () { return numeric.dot(A, A) })
|
|
bench.add('matrix operations numericjs A\'', function () { return numeric.transpose(A) })
|
|
bench.add('matrix operations numericjs det(A)', function () { return numeric.det(A) })
|
|
})();
|
|
|
|
// ndarray
|
|
(function () {
|
|
const A = pack(fiedler)
|
|
const B = zeros([25, 25])
|
|
|
|
bench.add('matrix operations ndarray A+A', function () { return ops.add(B, A, A) })
|
|
bench.add('matrix operations ndarray A*A', function () { return gemm(B, A, A) })
|
|
bench.add('matrix operations ndarray A\'', function () { ops.assign(B, A); return B.transpose(1, 0) })
|
|
bench.add('matrix operations ndarray det(A)', function () { return det(A) })
|
|
})()
|
|
|
|
// eigen-js
|
|
await eig.ready
|
|
await (function () {
|
|
const A = new eig.Matrix(fiedler)
|
|
|
|
bench.add('matrix operations eigen-js A+A', function () { return A.matAdd(A) })
|
|
bench.add('matrix operations eigen-js A*A', function () { return A.matMul(A) })
|
|
bench.add('matrix operations eigen-js A\'', function () { return A.transpose() })
|
|
bench.add('matrix operations eigen-js det(A)', function () { return A.det() })
|
|
})()
|
|
|
|
bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task)))
|
|
await bench.run()
|
|
})().catch(console.error)
|