Pages: [1]   Go Down
Author Topic: Well this is cute: an easy way of saving RAM  (Read 666 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Version 1.0 of the IDE does have the nice feature of allowing you to directly access strings from program memory. In particular, compare this:

Code:
#include <Streaming.h>

void setup ()
{
  Serial.begin (115200);
  Serial << "test: " << ("The slythy toves did gyre and gimble in the wabe.") << endl;
}

void loop() {}

... to:

Code:
#include <Streaming.h>

void setup ()
{
  Serial.begin (115200);
  Serial << "test: " << F("The slythy toves did gyre and gimble in the wabe.") << endl;
}

void loop() {}

The addition of the letter F around the string has saved 50 bytes of RAM! And it is hardly much work to do. smiley-razz

Plus, it works with the Streaming library, which is handy for other reasons, like imbedding variables and printing floating-point numbers. For example:

Code:
  Serial << F("The slythy toves did gyre and gimble in the wabe. ") << 42.42 << endl;
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That looks simple. I actually like the streaming library, much neater than a stack of prints and easier to understand than sprintf, I guess it's not used much because it's too resource hungry but that should change with the Due.

I assume that the F will not be required though on an ARM machine.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Resource hungry?

Code:
#include <Streaming.h>

void setup ()
{
  Serial.begin (115200);
  Serial << "test: " << F("The slythy toves did gyre and gimble in the wabe.") << endl;
}

void loop() {}

Code:
Binary sketch size: 2092 bytes (of a 32256 byte maximum)



Code:
void setup ()
{
  Serial.begin (115200);
  Serial.print ("test: ");
  Serial.println (F("The slythy toves did gyre and gimble in the wabe."));
}

void loop() {}

Code:
Binary sketch size: 2126 bytes (of a 32256 byte maximum)



The "old fashioned" way took more program memory, not less.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well cut off me legs and call me shorty.

I never checked, just assumed smiley

I can see a lot more streaming in my future.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6637
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Resource hungry?
The first version of my "fusebytes" sketch (which does little other than print strings) grew about 40% going from a homebrew flash_print function to streaming:

Code:
#ifdef USEFLASHLIB
#include "Flash.h"
#define fp(string) Serial << F(string)
#else
#include <avr/pgmspace.h>
#define fp(string) flashprint(PSTR(string))
void flashprint (const char p[])
{
    byte c;
    while (0 != (c = pgm_read_byte(p++))) {
Serial.write(c);
    }
}
#endif
IIRC, each use of the streaming operator adds "a few" instructions to do the indirection, more than doubling the size of the function linkage.  A couple of uses are fine, but it adds up...
Logged

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Resource hungry?
The first version of my "fusebytes" sketch (which does little other than print strings) grew about 40% going from a homebrew flash_print function to streaming

I think the real test is comparing against code that uses a lot of printf_P and sprintf_P's do to formatted output.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A quick test seems to bear out that the streaming library has an overhead of around 3 bytes per string. Test sketch:

Code:
//#define USEFLASHLIB

#ifdef USEFLASHLIB
  #include <Streaming.h>
  #define fp(string) Serial << F(string)
#else
  #define fp(string) flashprint(PSTR(string))
  
   void flashprint (const char p[])
    {
      byte c;
      while (0 != (c = pgm_read_byte(p++))) {
   Serial.write(c);
      }
    }
#endif

void setup ()
{
  Serial.begin (115200);
  
  fp ("Lorem");
  fp ("ipsum");
  fp ("dolor");
  fp ("sit");
  fp ("amet");
  fp ("consectetur");
  fp ("adipisicing");
  fp ("elit");
  fp ("sed");
  fp ("do");
  fp ("eiusmod");
  fp ("tempor");
  fp ("incididunt");
  fp ("ut");
  fp ("labore");
  fp ("et");
  fp ("dolore");
  fp ("magna");
  fp ("aliqua");
  fp ("Ut");
  fp ("enim");
  fp ("ad");
  fp ("minim");
  fp ("veniam");
  fp ("quis");
  fp ("nostrud");
  fp ("exercitation");
  fp ("ullamco");
  fp ("laboris");
  fp ("nisi");
  fp ("ut");
  fp ("aliquip");
  fp ("ex");
  fp ("ea");
  fp ("commodo");
  fp ("consequat");
  fp ("Duis");
  fp ("aute");
  fp ("irure");
  fp ("dolor");
  fp ("in");
  fp ("reprehenderit");
  fp ("in");
  fp ("voluptate");
  fp ("velit");
  fp ("esse");
  fp ("cillum");
  fp ("dolore");
  fp ("eu");
  fp ("fugiat");
  fp ("nulla");
  fp ("pariatur");
  fp ("Excepteur");
  fp ("sint");
  fp ("occaecat");
  fp ("cupidatat");
  fp ("non");
  fp ("proident");
  fp ("sunt");
  fp ("in");
  fp ("culpa");
  fp ("qui");
  fp ("officia");
  fp ("deserunt");
  fp ("mollit");
  fp ("anim");
  fp ("id");
  fp ("est");
  fp ("laborum");
  
}

void loop () {}


Using streaming, sketch size is 3028 bytes. Without it is 2842. Difference: 186 bytes. Number of prints: 69. So about 2.7 bytes each (strangely).

I make that about 6.5% larger, not 40%.

No doubt your overall sketch was more complex, but for something like this, the overheads, whilst they are there, aren't too bad.
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6637
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah.  The current version of Streaming.h seems to be much better than the one I downloaded before.
fusebytes.h is now also only slightly bigger in the stream-using version.
Logged

Pages: [1]   Go Up
Jump to: