Whats the most efficient way to declare many constants?

I have the following code which uses a large number of constants within a function that is called frequently. What is the best way to declare and initialise so many constants? As you can see they are in an array so they can be called via index i in the function.

I dont want to write out a massive formula with 12 x 3 actual constants. If I declare these as global variables, they take up a lot of memory, but if I declare these in the function, does it mean they are continuously initialised and then destroyed in memory each time the function is called?

My ultimate objective is to reduce energy use as this is for a battery operated device. Computational speed is not so important.

Thanks in advance!

class Constituent {
  public:
    double ampl;
    double freq;
    double phase;
  };

Constituent MBC[12];

void setup() {
  MBC[1].freq = 0;
  MBC[1].ampl = 1.67848475072895;
  MBC[1].phase = 90;
  MBC[2].freq = 0.0805114007;
  MBC[2].ampl = 1.04142143756596;
  MBC[2].phase = 293.802032693943;
  // etc ...
}

double GetAmpl(double t) {
  double Ampl = 0;
  for (int i = 1; i <= 12; i++) {
      Ampl = Ampl + MBC[i].ampl * sin(2 * PI * MBC[i].freq * t + MBC[i].phase * PI / 180);
  }
  return Ampl ;
}

If they are constant, declare them as constant...
The compiler might get rid of some via substitution.
Also, floats can hold 6to 7 digits, so you will lose precision and you could save time by only typing 7 decimals.

I do not think power consumption will be changed this way. The clock will run with or without instructions...

You can put your MCU to sleep but then you need some trigger for wake up.

If you put them inside the function they (or less of them after substitution) will be created and destroyed each time the function is called. I think they belong in the function... if you do want this overhead you can declare them static instead of global.

Is MBC[] a property of constituent?
Then it should be inside your class (from a OOP point of view).

it seems to me as a simple struct rather than a class (which kinda are the same thing if you make the members public)

struct t_constituent {
  const double ampl;
  const double freq;
  const double phase;
};

and you would define and provide values to a local or global array this way

const t_constituent MBC[] = {
  { 0.0         , 1.67848475072895,  90.0            },
  { 0.0805114007, 1.04142143756596, 293.802032693943 },
  ...
};

const size_t mbcCount = sizeof MBC / sizeof *MBC;

local arrays are allocated on the stack, so initialized every time you call the function. if it's too much of a penalty then consider a global array. As they are const you could also store the array in flash (PROGMEM on AVR)


Side note
be careful as your code starts initialising the array with index 1,

the first entry is really at index 0 and if you have 12 elements the last one is 11 - not 12. using 12 would overflow

1 Like

Depends on your definition of "a lot". Since you're using 'double', I assume you're programming for an ARM or ESP32/ESP8266 that really supports 'double'. So, 12 x 3 x 8 = 288 bytes. Not really 'a lot' given available memory on those processors.

If it's an AVR processor, then it doesn't support 'double' anyway. So, 12 x 3 x 4 = 144. Still not 'a lot'.

and you can store those in PROGMEM if really SRAM becomes an issue

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.