hherbol
hherbol

Reputation: 91

initializing an array of constants in a struct

To stack overflow members, I am coding a simulator that requires multiple loops (sometimes over 1,000,000) that each involves heavy calculations. Thus, saving 10 millisecond on a loop can lead to saving over 160 extra minutes of calculations. So I am fighting for every code optimization I can get. Previously I had imported all my system parameters from a file into vectors. After awhile I realized that:

  1. Calling a constant int/double/... is faster than calling a regular int/double/...
  2. Using arrays is faster than using vectors
  3. I did not need the full functionality of std::string and could make a simple knockoff version of it to use

Originally I naively thought I could just convert std::vector<double> to std::vector<const double>. As I've been also trying to make this cross-platform with linux I found that the visual studio express compiler ignores the fact that const can't be declared like that (and linux just throws a ton of errors).

I decided that I would use constant arrays in the structs I was initializing; however, could not figure out how to initialize it properly. (Most/all help forums I came across said to declare static const int* and initialize it as a global, which I don't think works for what I need). I finally developed this final solution; however, I believe I committed a 'taboo' as I ended up using a pointer to declare the constant. It compiles and runs with no errors and thus I was wondering, is it wrong to initialize a constant array using pointers? And if so, how else would you do it? (I understand it might be slower to get all data this way, but in the part where time matters it SHOULD be faster to call... I think)

#include <stdio.h>
#include <malloc.h>
#include <conio.h>

#if defined(_WIN32) || defined(_WIN64)
#define gsize _msize
#else
#define gsize malloc_usable_size
#endif

struct testy{
    const int *i;
    const double *d;
    testy(){
        i=(const int *)malloc(0);
        d=(const double *)malloc(0);
    }
};

inline const int* getDat(const int* dst, int* src){
    dst=(const int*)realloc((void *)dst,gsize((void *)src)); // Allocate enough memory to hold the data
    return src;
}

inline const double* getDat(const double* dst, double* src){
    dst=(const double*)realloc((void *)dst,gsize((void *)src)); // Allocate enough memory to hold the data
    return src;
}

int main(){
    testy data;
    int *tmp_i = (int *)malloc(0);
    double *tmp_d = (double *)malloc(0);

    for(int i=0;i<3;i++){ // load empty array with what i want
        tmp_i=(int*)realloc((void *)tmp_i,gsize((void *)tmp_i)+1*sizeof(int)); // Increase size by one
        tmp_i[i]=i;
    }
    for(int i=0;i<3;i++){ // load empty array with what i want
        tmp_d=(double*)realloc((void *)tmp_d,gsize((void *)tmp_d)+1*sizeof(double)); // Increase size by one
        tmp_d[i]=i;
    }

    data.i=getDat(data.i,tmp_i);
    data.d=getDat(data.d,tmp_d);

    printf("\nIntegers\n");
    for(int i=0;i<(gsize((void *)data.i)/sizeof(int));i++)
        printf("%d\t",data.i[i]);

    printf("\nDoubles\n");
    for(int i=0;i<(gsize((void *)data.d)/sizeof(double));i++)
        printf("%lg\t",data.d[i]);

    free(tmp_i); free(tmp_d);
    _getch();
    return 0;
}

I removed the knockoff string and its uses from this code as there were some issues with declaring the array of it and I didn't want to ask more than one question here.

Upvotes: 3

Views: 527

Answers (1)

Ed Heal
Ed Heal

Reputation: 60037

  1. Remove realloc. That is expensive and also fragments memory
  2. const will not make any difference - you have to access memory at the end of the day and the const bit just ensures you do not alter things that you shouldn't
  3. Place things like (gsize((void *)data.d)/sizeof(double) outside the for loop if the value is immutable. Prevents a function call each time around the loop
  4. Make the memory cache work. i.e. access stuff in memory sequentially. The data shipped from memory to the processor can be pre-fetched easily.
  5. As to doing any complex operations (that you have not shown) use a little algebra to simplify the equations. If possible use integers over doubles if possible, This depends on the problem space.

Upvotes: 3

Related Questions