user11254: I have lots of Serial.print() and Serial.println() statements throughout my (rather large) program for debugging when things fail. I've commented out the Serial.begin() statement so I don't slow down execution by running a serial port. However, I'd like to leave the Serial.print() calls so I only have to uncomment Serial.begin() later on.
If there is no Serial port active on the device, are the Serial.print() lines still executed at runtime, or does the compiler ignore them? Is there any performance advantage to explicitly commenting out those lines?

user22924: The compiler cannot know what the situation with the device is at runtime. The function itself must determine that, so the call will take place, with arguments and everything. A well-written function would test early on whether there was anything to do, and if not then return early - but that still wastes time.
The norm in programming is to have two versions of the code: one labelled "DEBUG", which has lots of print()s, and one labelled "RELEASE", which uses language contructs to ignore them. This is achieved a number of different ways - but Arduino doesn't really support this out of the box.
@KIIV's answer, using #define, is one way to do this. The problem with it comes when you have multiple modules, or are using libraries that themselves do their own print()s. If you only have your main sketch, then it would work fairly well.

user10794: A quick test shows that not doing a Serial.begin makes things run 10 times as fast. For example:
void setup ()
  {
  Serial.begin (115200);
  pinMode (13, OUTPUT);
  }  // end of setup

void loop ()
  {
  digitalWrite (13, HIGH);
  for (byte i = 0; i < 100; i++)
    Serial.println ("But does it get goat's blood out?");
  digitalWrite (13, LOW);
  delay (500);
  }  // end of loop

That took 292 ms to do 100 x of those prints on my Uno. If I comment out the Serial.begin call it takes 29 ms. So, faster but not incredibly fast. 
On my page about debugging I have suggested code to turn on or off debugging prints. The basic idea is to have a Trace define that lets you output stuff if debugging is on, like this:
#define DEBUG false

// conditional debugging
#if DEBUG 

  #define beginDebug()  do { Serial.begin (115200); } while (0)
  #define Trace(x)      Serial.print   (x)
  #define Trace2(x,y)   Serial.print   (x,y)
  #define Traceln(x)    Serial.println (x)
  #define Traceln2(x,y) Serial.println (x,y)
  #define TraceFunc()   do { Serial.print (F("In function: ")); Serial.println (__PRETTY_FUNCTION__); } while (0)


#else
  #define beginDebug()  ((void) 0)
  #define Trace(x)      ((void) 0)
  #define Trace2(x,y)   ((void) 0)
  #define Traceln(x)    ((void) 0)
  #define Traceln2(x,y) ((void) 0)
  #define TraceFunc()   ((void) 0)
#endif // DEBUG


void setup ()
  {
  beginDebug ();
  pinMode (13, OUTPUT);
  }  // end of setup

void loop ()
  {
  digitalWrite (13, HIGH);
  for (byte i = 0; i < 100; i++)
    Traceln ("But does it get goat's blood out?");
  digitalWrite (13, LOW);
  delay (500);
  }  // end of loop

Now in this case, with DEBUG defined as false, the time taken with pin 13 high is now only 5 µs - a substantial speed-up.
If you define DEBUG to be true, then it is much slower - 290 ms as in the first test.

The suggestion made by KIIV will fail if you have if statements:
#ifdef NDEBUG
  #define LOG(...)
  #define LOGLN(...)
#else
  #define LOG(...) Serial.print(__VA_ARGS__);
  #define LOGLN(...) Serial.println(__VA_ARGS__);
#endif

For example:
if (something)
   LOG ("something is true");

digitalWrite (8, HIGH);

Imagine that debugging is off. Now the empty define makes the code look like:
if (something)
  digitalWrite (8, HIGH);

So you have a side-effect that the code behaves differently if debugging is off.


Semicolon is not part of the macro, so it will be expanded into: if (something) ;

See What does the c precompiler do with macros defined as (void)0 - there are subtle issues with using an empty define compared to void(0).
For example:
  Serial.println ("hi there"), LOGLN ("debugging");

That fails to compile (with the empty define) if debugging is off. The void(0) version does compile. Admittedly it's an edge case, but nevertheless ...

user23841: No, there is no USART wasn't enabled so skip all prints. Everything must be done anyways (calls, conversions to strings, writes to UDR - USART Data Register). It is just not sent outside by USART and it doesn't have to wait for UDRE (USART Data Register Empty flag) so it might be slightly faster.
You can use similar technique as Loggers - log level variable and ifs (this can be changed runtime).
Or you can use macros:
// comment out this line, if you want to show logs:
#define NDEBUG

#ifdef NDEBUG
  #define LOG(...)
  #define LOGLN(...)
#else
  #define LOG(...) Serial.print(__VA_ARGS__)
  #define LOGLN(...) Serial.println(__VA_ARGS__)
#endif

And later:
LOG(F("Something: 0x"));
LOGLN(variable, HEX);

And how it looks after macro substitution? For code:
if (...) LOG(F("something")); else LOG(F("something else"));

With NDEBUG defined it's expanded to:
if (...) ; else ;

And without NDEBUG defined it's expanded to:
if (...) Serial.print(F("something")); else Serial.print(F("something else"));


11254: <p>I have lots of <code>Serial.print()</code> and <code>Serial.println()</code> statements throughout my (rather large) program for debugging when things fail. I've commented out the <code>Serial.begin()</code> statement so I don't slow down execution by running a serial port. However, I'd like to leave the <code>Serial.print()</code> calls so I only have to uncomment <code>Serial.begin()</code> later on.</p>

<p>If there is no Serial port active on the device, are the <code>Serial.print()</code> lines still executed at runtime, or does the compiler ignore them? Is there any performance advantage to explicitly commenting out those lines?</p>
 22924: <p>The compiler cannot know what the situation with the device is at runtime. The function itself must determine that, so the call <em>will</em> take place, with arguments and everything. A well-written function would test early on whether there was anything to do, and if not then return early - but that still wastes time.</p>

<p>The norm in programming is to have two versions of the code: one labelled "DEBUG", which has lots of <code>print()</code>s, and one labelled "RELEASE", which uses language contructs to ignore them. This is achieved a number of different ways - but Arduino doesn't really support this out of the box.</p>

<p>@KIIV's answer, using <code>#define</code>, is one way to do this. The problem with it comes when you have multiple modules, or are using libraries that themselves do their own <code>print()</code>s. If you only have your main sketch, then it would work fairly well.</p>
 10794: <p>A quick test shows that not doing a Serial.begin makes things run 10 times as fast. For example:</p>

<pre class="lang-c++ prettyprint-override"><code>void setup ()
  {
  Serial.begin (115200);
  pinMode (13, OUTPUT);
  }  // end of setup

void loop ()
  {
  digitalWrite (13, HIGH);
  for (byte i = 0; i &lt; 100; i++)
    Serial.println ("But does it get goat's blood out?");
  digitalWrite (13, LOW);
  delay (500);
  }  // end of loop
</code></pre>

<p>That took 292 ms to do 100 x of those prints on my Uno. If I comment out the Serial.begin call it takes 29 ms. So, faster but not incredibly fast. </p>

<p>On <a href="http://www.gammon.com.au/forum/?id=11329" rel="nofollow noreferrer">my page about debugging</a> I have suggested code to turn on or off debugging prints. The basic idea is to have a Trace define that lets you output stuff if debugging is on, like this:</p>

<pre class="lang-c++ prettyprint-override"><code>#define DEBUG false

// conditional debugging
#if DEBUG 

  #define beginDebug()  do { Serial.begin (115200); } while (0)
  #define Trace(x)      Serial.print   (x)
  #define Trace2(x,y)   Serial.print   (x,y)
  #define Traceln(x)    Serial.println (x)
  #define Traceln2(x,y) Serial.println (x,y)
  #define TraceFunc()   do { Serial.print (F("In function: ")); Serial.println (__PRETTY_FUNCTION__); } while (0)


#else
  #define beginDebug()  ((void) 0)
  #define Trace(x)      ((void) 0)
  #define Trace2(x,y)   ((void) 0)
  #define Traceln(x)    ((void) 0)
  #define Traceln2(x,y) ((void) 0)
  #define TraceFunc()   ((void) 0)
#endif // DEBUG


void setup ()
  {
  beginDebug ();
  pinMode (13, OUTPUT);
  }  // end of setup

void loop ()
  {
  digitalWrite (13, HIGH);
  for (byte i = 0; i &lt; 100; i++)
    Traceln ("But does it get goat's blood out?");
  digitalWrite (13, LOW);
  delay (500);
  }  // end of loop
</code></pre>

<p>Now in this case, with DEBUG defined as <code>false</code>, the time taken with pin 13 high is now only 5 µs - a substantial speed-up.</p>

<p>If you define DEBUG to be true, then it is much slower - 290 ms as in the first test.</p>

<hr>

<p>The suggestion made by KIIV will fail if you have <code>if</code> statements:</p>

<pre class="lang-c++ prettyprint-override"><code>#ifdef NDEBUG
  #define LOG(...)
  #define LOGLN(...)
#else
  #define LOG(...) Serial.print(__VA_ARGS__);
  #define LOGLN(...) Serial.println(__VA_ARGS__);
#endif
</code></pre>

<p>For example:</p>

<pre class="lang-c++ prettyprint-override"><code>if (something)
   LOG ("something is true");

digitalWrite (8, HIGH);
</code></pre>

<p>Imagine that debugging is off. Now the empty define makes the code look like:</p>

<pre class="lang-c++ prettyprint-override"><code>if (something)
  digitalWrite (8, HIGH);
</code></pre>

<p>So you have a side-effect that the code behaves differently if debugging is off.</p>

<hr>

<blockquote>
  <p>Semicolon is not part of the macro, so it will be expanded into: <code>if (something) ;</code></p>
</blockquote>

<p>See <a href="https://stackoverflow.com/questions/25021081/what-does-the-c-precompiler-do-with-macros-defined-as-void0">What does the c precompiler do with macros defined as (void)0</a> - there are subtle issues with using an empty define compared to void(0).</p>

<p>For example:</p>

<pre><code>  Serial.println ("hi there"), LOGLN ("debugging");
</code></pre>

<p>That fails to compile (with the empty define) if debugging is off. The <code>void(0)</code> version does compile. Admittedly it's an edge case, but nevertheless ...</p>
 23841: <p>No, there is no <code>USART</code> wasn't enabled so skip all <code>print</code>s. Everything must be done anyways (calls, conversions to strings, writes to <code>UDR</code> - <code>USART Data Register</code>). It is just not sent outside by <code>USART</code> and it doesn't have to wait for <code>UDRE</code> (<code>USART Data Register Empty</code> flag) so it might be slightly faster.</p>

<p>You can use similar technique as Loggers - log level variable and <code>if</code>s (this can be changed runtime).</p>

<p>Or you can use macros:</p>

<pre><code>// comment out this line, if you want to show logs:
#define NDEBUG

#ifdef NDEBUG
  #define LOG(...)
  #define LOGLN(...)
#else
  #define LOG(...) Serial.print(__VA_ARGS__)
  #define LOGLN(...) Serial.println(__VA_ARGS__)
#endif
</code></pre>

<p>And later:</p>

<pre><code>LOG(F("Something: 0x"));
LOGLN(variable, HEX);
</code></pre>

<p>And how it looks after macro substitution? For code:</p>

<pre><code>if (...) LOG(F("something")); else LOG(F("something else"));
</code></pre>

<p>With NDEBUG defined it's expanded to:</p>

<pre><code>if (...) ; else ;
</code></pre>

<p>And without NDEBUG defined it's expanded to:</p>

<pre><code>if (...) Serial.print(F("something")); else Serial.print(F("something else"));
</code></pre>
