ScalerByLeo/Src/Scaler/Bench/Mean.mq5

155 lines
4.2 KiB
MQL5

2026-09-15 11:21:44 -05:00
//+------------------------------------------------------------------+
//| MatMulBench.mq5 |
//| Benchmark: matrix nativo vs manual vs array |
//+------------------------------------------------------------------+
#property copyright "Benchmark"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| 1) Multiplicación MANUAL usando el tipo matrix (indexado a mano) |
//+------------------------------------------------------------------+
bool MatMulManual(const matrix &A, const matrix &B, matrix &C)
{
ulong n = A.Rows();
ulong k = A.Cols();
ulong m = B.Cols();
if(B.Rows() != k)
return false;
C = matrix::Zeros(n, m);
for(ulong i = 0; i < n; i++)
{
for(ulong j = 0; j < m; j++)
{
double sum = 0.0;
for(ulong p = 0; p < k; p++)
sum += A[i][p] * B[p][j];
C[i][j] = sum;
}
}
return true;
}
//+------------------------------------------------------------------+
//| 2) Multiplicación NATIVA (operador MatMul de matrix) |
//+------------------------------------------------------------------+
bool MatMulNative(const matrix &A, const matrix &B, matrix &C)
{
C = A.MatMul(B);
return true;
}
//+------------------------------------------------------------------+
//| 3) Multiplicación emulando matrix con double[] planos (row-major)|
//+------------------------------------------------------------------+
bool MatMulArray(const double &A[], const double &B[], double &C[],
int n, int k, int m)
{
ArrayResize(C, (int)(n * m));
ArrayInitialize(C, 0.0);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
double sum = 0.0;
int aBase = i * k;
for(int p = 0; p < k; p++)
sum += A[aBase + p] * B[p * m + j];
C[i * m + j] = sum;
}
}
return true;
}
//+------------------------------------------------------------------+
//| Helpers para llenar con datos aleatorios |
//+------------------------------------------------------------------+
matrix RandMatrix(ulong rows, ulong cols)
{
matrix m(rows, cols);
for(ulong i = 0; i < rows; i++)
for(ulong j = 0; j < cols; j++)
m[i][j] = (double)MathRand() / 32767.0;
return m;
}
void RandArray(double &arr[], int n, int m)
{
ArrayResize(arr, n * m);
for(int i = 0; i < n * m; i++)
arr[i] = (double)MathRand() / 32767.0;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
const int N = 600; // dimensión de las matrices NxN
const int ITER = 300; // repeticiones
MathSrand(42);
//--- Preparar datos base (matrix)
matrix Am = RandMatrix(N, N);
matrix Bm = RandMatrix(N, N);
//--- Preparar datos base (array plano)
double Aa[], Ba[];
ArrayResize(Aa, N * N);
ArrayResize(Ba, N * N);
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
{
Aa[i * N + j] = Am[i][j];
Ba[i * N + j] = Bm[i][j];
}
double checksum = 0.0;
//=== 1) Manual con matrix ===
{
matrix C;
ulong a = GetMicrosecondCount();
for(int it = 0; it < ITER; it++)
{
MatMulManual(Am, Bm, C);
checksum += C[0][0];
}
ulong b = GetMicrosecondCount();
Print("1) Manual (matrix indexado): ", (b - a), " us checksum=", checksum);
}
//=== 2) Nativo MatMul ===
{
matrix C;
checksum = 0.0;
ulong a = GetMicrosecondCount();
for(int it = 0; it < ITER; it++)
{
MatMulNative(Am, Bm, C);
checksum += C[0][0];
}
ulong b = GetMicrosecondCount();
Print("2) Nativo (A.MatMul(B)): ", (b - a), " us checksum=", checksum);
}
//=== 3) Emulado con double[] ===
{
double C[];
checksum = 0.0;
ulong a = GetMicrosecondCount();
for(int it = 0; it < ITER; it++)
{
MatMulArray(Aa, Ba, C, N, N, N);
checksum += C[0];
}
ulong b = GetMicrosecondCount();
Print("3) Array double[] (row-major):", (b - a), " us checksum=", checksum);
}
}
//+------------------------------------------------------------------+