From c1d08e30444ee58596f91b6f2968a7e521c08dc2 Mon Sep 17 00:00:00 2001 From: Frederik Beimgraben Date: Fri, 17 Jan 2025 20:24:35 +0100 Subject: [PATCH] Refactor any copying of arrays for performance using memcpy --- MMS24-25.c | 45 ++++++++++++++++++++------------------------- Makefile | 2 +- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/MMS24-25.c b/MMS24-25.c index 26a74e6..72ece9d 100644 --- a/MMS24-25.c +++ b/MMS24-25.c @@ -15,6 +15,7 @@ #include #include #include +#include #include // For variadic functions // UNIX Libraries @@ -118,6 +119,20 @@ void _warn(char *fmt, ...) { } // #endregion +/* + * Copies an array of doubles *fast*. + */ +void _copy_double_array(double *dst, double *src, int len) { + memcpy(dst, src, len * sizeof(double)); +} + +/* + * Copies an array of integers *fast*. + */ +void _copy_int_array(int *dst, int *src, int len) { + memcpy(dst, src, len * sizeof(int)); +} + // #region C99 Compatibility #if _GNU_SOURCE || _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 #else @@ -439,9 +454,7 @@ LocalExtrema* copyLocalExtrema(LocalExtrema *pexIn) { if (localExtrema->piLocalExtremaPos == NULL) _mem_error("copyLocalExtrema: Failed to allocate memory for localExtrema->piLocalExtremaPos"); - for (int i = 0; i < pexIn->iNumLocalExtrema; i++) { - localExtrema->piLocalExtremaPos[i] = pexIn->piLocalExtremaPos[i]; - } + _copy_int_array(localExtrema->piLocalExtremaPos, pexIn->piLocalExtremaPos, pexIn->iNumLocalExtrema); return localExtrema; } @@ -478,9 +491,7 @@ MMSignal *createSignalFromSignal(MMSignal *pmmsIn) { if (signal->pdValues == NULL) _mem_error("createSignalFromSignal: Failed to allocate memory for signal->pdValues"); - for (int i = 0; i < pmmsIn->iNumValues; i++) { - signal->pdValues[i] = pmmsIn->pdValues[i]; - } + _copy_double_array(signal->pdValues, pmmsIn->pdValues, pmmsIn->iNumValues); } else { if (pmmsIn->iNumValues != 0) _error("createSignalFromSignal: pmmsIn->pdValues is NULL while pmmsIn->iNumValues is not %d", pmmsIn->iNumValues); @@ -539,9 +550,7 @@ MMSignal *createSignalFromDoubleArray(int iArrayLen, double *pdIn) { if (signal->pdValues == NULL) _mem_error("createSignalFromDoubleArray: Failed to allocate memory for signal->pdValues"); - for (int i = 0; i < iArrayLen; i++) { - signal->pdValues[i] = pdIn[i]; - } + _copy_double_array(signal->pdValues, pdIn, iArrayLen); signal->iNumValues = iArrayLen; @@ -720,14 +729,12 @@ double calculateMedian(double *pdIn, int iLen) { } double *pdInSorted = NULL; - pdInSorted = (double*) malloc(sizeof(double) *iLen); + pdInSorted = (double*) malloc(sizeof(double) * iLen); if (pdInSorted == NULL) _mem_error("calculateMedian: Failed to allocate memory for pdInSorted"); - for (int i = 0; i < iLen; i++) { - pdInSorted[i] = pdIn[i]; - } + _copy_double_array(pdInSorted, pdIn, iLen); // Sort the array using stdlib's qsort function qsort(pdInSorted, iLen, sizeof(double), compareDoubles); @@ -900,18 +907,6 @@ Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) { if (iNumBins == 0) _error("initHistogram: iNumBins must be non-0"); - /*if (iLen == 0) // FIXME: This should be an error in the final version - _error("initHistogram: iLen is 0"); - - histogram->dIntervalMin = pdIn[0]; - histogram->dIntervalMax = pdIn[0]; - for (int i = 0; i < iLen; i++) { - if (pdIn[i] < histogram->dIntervalMin) - histogram->dIntervalMin = pdIn[i]; - if (pdIn[i] > histogram->dIntervalMax) - histogram->dIntervalMax = pdIn[i]; - }*/ - int minPos, maxPos; getMinMaxPos(pdIn, iLen, &minPos, &maxPos); histogram->dIntervalMin = pdIn[minPos]; diff --git a/Makefile b/Makefile index f1301eb..600c731 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc SOURCE_FILE=MMS24-25.c -OPTS=-lm -D _DEBUG +OPTS=-lm -D _DEBUG -std=c99 all: clean tests run