Question about Optimizing Code/Memory

Hi ArduinoFellas,

I have a question about code optimization:

For testing what would be the most efficient code, I changed only a section of my test sketch as depicted below, compiled and take note about the compiler results on memory usage, as follows:

  if (RTC.read(tm)) {
    digitalWrite(OnBoardLED, HIGH);   // turn the onboard LED on
    // Calendar Day
    Day = tm.Day;
    // Calendar Month
    Month = tm.Month;
    // Calendar Year
    Year = (tmYearToCalendar(tm.Year) - 2000); // Prints only last 2-digit year
    // Calendar Hours
    Hours = tm.Hour;
    // Calendar Minutes
    Minutes = tm.Minute;
    // Calendar Seconds
    // Seconds = tm.Second;
    // Temperature
    Temperature = DHT11.temperature, 1;
    // Relative Humidity
    Hum = DHT11.humidity, 0;
    // Barometric pressure
    Baro = 1061.2;
    // Dew Point
    DP = dewPoint(DHT11.temperature, DHT11.humidity);
    // Dew Point Fast
    // DP = dewPointFast(DHT11.temperature, DHT11.humidity);
    DP = ((int)(DP * 100)/100.0);
    // Print to serial port if need.
    // 'slash' used as Date separator, 'semicolon' used as Field separator
    if (PrintSerial == true){
        DummyString = DigitToString(Day) + slash + DigitToString(Month) + slash + DigitToString(Year) + semicolon + DigitToString(Hours) + colons + DigitToString(Minutes) + semicolon + DigitToString(Temperature) + semicolon + DigitToString(Hum) + semicolon + Baro + semicolon + DP + semicolon + EEPROMAddress + Asterix;
        Serial.println(DummyString); // Prints and ends line with CR + LF
    }

The compiler says the following:
// Sketch uses 13,168 bytes (42%) of program storage space. Maximum is 30,720 bytes.
// Global variables use 672 bytes (32%) of dynamic memory, leaving 1,376 bytes for local variables.
// Maximum is 2,048 bytes.

  if (RTC.read(tm)) {
    digitalWrite(OnBoardLED, HIGH);   // turn the onboard LED on
    // Calendar Day
    Day = tm.Day;
    // Calendar Month
    Month = tm.Month;
    // Calendar Year
    Year = (tmYearToCalendar(tm.Year) - 2000); // Prints only last 2-digit year
    // Calendar Hours
    Hours = tm.Hour;
    // Calendar Minutes
    Minutes = tm.Minute;
    // Calendar Seconds
    // Seconds = tm.Second;
    // Temperature
    Temperature = DHT11.temperature, 1;
    // Relative Humidity
    Hum = DHT11.humidity, 0;
    // Barometric pressure
    Baro = 1061.2;
    // Dew Point
    DP = dewPoint(DHT11.temperature, DHT11.humidity);
    // Dew Point Fast
    // DP = dewPointFast(DHT11.temperature, DHT11.humidity);
    DP = ((int)(DP * 100)/100.0);
    // Print to serial port if need.
    // 'slash' used as Date separator, 'semicolon' used as Field separator
    if (PrintSerial == true){
        Serial.println(DigitToString(Day));
        Serial.println(slash);
        Serial.println(DigitToString(Month));
        Serial.println(slash);
        Serial.println(DigitToString(Year));
        Serial.println(semicolon);
        Serial.println(DigitToString(Hours));
        Serial.println(colons);
        Serial.println(DigitToString(Minutes));
        Serial.println(semicolon);
        Serial.println(DigitToString(Temperature));
        Serial.println(semicolon);
        Serial.println(DigitToString(Hum));
        Serial.println(semicolon);
        Serial.println(Baro);
        Serial.println(semicolon);
        Serial.println(DP);
        Serial.println(semicolon);
        Serial.println(EEPROMAddress);
        Serial.println(Asterix);
        Serial.println(DummyString); // Prints and ends line with CR + LF
    }

Compiler results:
// Sketch uses 12,410 bytes (40%) of program storage space. Maximum is 30,720 bytes.
// Global variables use 684 bytes (33%) of dynamic memory, leaving 1,364 bytes for local variables.
// Maximum is 2,048 bytes.

For some reason, the code with multiple Serial.println() callings use less program storage than the other with a single Serial.println() call, could somebody explain me why I got this odd(?) behavior?

Thanks in advance

It's hard to determine entire program statistics base upon a code fragment.

Hello,

First code uses more memory because you use a String object and operators of the String class, in addition to the Serial.println function.

Second code just make many calls to the Serial.println function. Calling a function multiple times doesn't take much memory, the function is defined only once, it's not like the function was copied again and again each time you call it :P.

How much RAM do you suppose DummyString consumes?

I did the same thing you are doing with client.print by cutting the this stuff down into many sections that were the same in many cases

client.print("Click <a href="/H">here turn the LED on pin 9 on
");
client.print("Click <a href="/L">here turn the LED on pin 9 off
");]

if you cut it down for example make a few of these client.print("turn the LED on pin"); you see there were two times above that was printed, but by cutting it down it creates a string of it's own which it stores, and once it's stored, it's good to go always so theres no double writting it as far as the memory is concerned. Basically, if you wrote char turnledon[] = "turn the Led on pin"; up top as a global, then in client print you used client.print(turnledon); many times, its pretty much the same concept. If you use Strings, and attach the whole thing (which the whole thing is different each time) instead of cutting the part into sections that some will be the same in multiple instances, it is able to Optimize the smaller cut sections that have multiples.

I hope that helps.

RayLivingston:
How much RAM do you suppose DummyString consumes?

I don't know!

How is supposed to measure it?

yv1hx:
I don't know!

How is supposed to measure it?

By reading and understanding MorganS's link right above your post.

what would be the most efficient code

memory efficient is not the same as performance efficient or energy efficient.

If a program does what it should do, does memory usage really matter?

performance efficient or energy efficient.

I know that memory efficient and performance efficient are complete opposites. To speed up how fast the program runs, you have to care less about memory. How do you make it power efficient though? If you make a boolean high does that use more power than a boolean that's low?

Depending on the external circuit, yes. An output that is high can sometimes use less power than an input which is floating.

That's really interesting. I kind of want to research this more, but I have my hands full at the moment learning about pointers and such.

Thanks you all guys, certainly I have learned a lot since posting this post.

Now I've cleared some portions of my code following the recomendations.

Thanks again :slight_smile: