user42: When you're writing a typical sketch, you usually rely on loop() being called repeatedly for as long as the Arduino is running. Moving in and out of the loop() function must introduce a small overhead though.
To avoid that, you could presumably create your own infinite loop, like this:
void loop()
{
    while (true)
    {
        // do stuff...
    }
}

Is that a viable way to improve performance? Will it cause other problems if loop() never returns?

user65: Cybergibbons's answer describes quite nicely the assembly code generation and the differences amongst the two techniques. This is intended to be a complementary answer looking at the issue in terms of practical differences, i.e. how much of a difference either approach will make in terms of execution time.

Code Variations
I did an analysis involving the following variations:

Basic void loop() (which gets inlined on compilation)
Un-inlined void loop() (using __attribute__ ((noinline)))
Loop with while(1) (which gets optimized)
Loop with un-optimized while(1) (by adding __asm__ __volatile__("");. This is a nop instruction that prevents optimization of the loop without resulting in additional overheads of a volatile variable)
An un-inlined void loop() with optimized while(1)
An un-inlined void loop() with un-optimized while(1)

The sketches can be found here.
Experiment
I ran each of these sketches for 30 seconds, thereby accumulating 300 data points each. There was a 100 millisecond delay call in each loop (without which bad things happen). 
Results
I then calculated the mean execution times of each loop, subtracted 100 milliseconds from each and then plotted the results. 
http://raw2.github.com/AsheeshR/Arduino-Loop-Analysis/master/Figures/timeplot.png
Conclusion

An un-optimised while(1) loop within void loop is faster than a compiler optimised  void loop. 
The time difference between the un-optimized code and default Arduino  optimized code is insignificant practically. You will be better off compiling manually using avr-gcc and using your own optimisation flags rather than depending on the Arduino IDE to help you with it (if you need microsecond optimisations). 



NOTE: The actual time values are not of significance here, the difference between them is. The ~90 microseconds of execution time includes a call to Serial.println, micros and delay.


NOTE2: This was done using the Arduino IDE and the default compiler flags that it supplies.


NOTE3: Analysis (plot and calculations) was done using R.


user136: The part of the code on an ATmega core that does setup() and loop() is at follows:
#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif

        setup();

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }

        return 0;
}

Pretty simple, but there is the overhead of the serialEventRun(); in there.
Let's compare two simple sketches:
void setup()
{

}

volatile uint8_t x;

void loop()
{

    x = 1;

}

and
void setup()
{

}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.
In the ASM produced, you get different results:

You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.
To generate ASM as above, you need to use a tool called avr-objdump. This is included with avr-gcc. Location varies depending on OS so it is easiest to search for it by name.
avr-objdump can operate on .hex files, but these are missing the original source and comments. If you have just built code, you will have a .elf file that does contain this data. Again, the location of these files varies by OS - the easiest way to locate them is to turn on verbose compilation in preferences and see where the output files are being stored.
Run the command as follows:

avr-objdump -S output.elf > asm.txt

And examine the output in a text editor.

42: <p>When you're writing a typical sketch, you usually rely on <code>loop()</code> being called repeatedly for as long as the Arduino is running. Moving in and out of the <code>loop()</code> function must introduce a small overhead though.</p>

<p>To avoid that, you could presumably create your own infinite loop, like this:</p>

<pre><code>void loop()
{
    while (true)
    {
        // do stuff...
    }
}
</code></pre>

<p>Is that a viable way to improve performance? Will it cause other problems if <code>loop()</code> never returns?</p>
 65: <p><a href="https://arduino.stackexchange.com/questions/337/would-an-infinite-loop-inside-loop-perform-faster#339">Cybergibbons's answer</a> describes quite nicely the assembly code generation and the differences amongst the two techniques. This is intended to be a complementary answer looking at the issue in terms of <em>practical</em> differences, i.e. how much of a difference either approach will make in terms of <em>execution time</em>.</p>

<hr>

<h2>Code Variations</h2>

<p>I did an <a href="http://github.com/AsheeshR/Arduino-Loop-Analysis" rel="nofollow noreferrer">analysis</a> involving the following variations:</p>

<ul>
<li>Basic <code>void loop()</code> (which gets inlined on compilation)</li>
<li>Un-inlined <code>void loop()</code> (using <code>__attribute__ ((noinline))</code>)</li>
<li>Loop with <code>while(1)</code> (which gets optimized)</li>
<li>Loop with un-optimized <code>while(1)</code> (by adding <code>__asm__ __volatile__("");</code>. This is a <code>nop</code> instruction that prevents optimization of the loop without resulting in additional overheads of a <code>volatile</code> variable)</li>
<li>An un-inlined <code>void loop()</code> with optimized <code>while(1)</code></li>
<li>An un-inlined <code>void loop()</code> with un-optimized <code>while(1)</code></li>
</ul>

<p>The sketches can be found <a href="http://github.com/AsheeshR/Arduino-Loop-Analysis/tree/master/Code/Sketches" rel="nofollow noreferrer">here</a>.</p>

<h2>Experiment</h2>

<p>I ran each of these sketches for 30 seconds, thereby accumulating <a href="http://github.com/AsheeshR/Arduino-Loop-Analysis/tree/master/Data" rel="nofollow noreferrer">300 data points each</a>. There was a 100 millisecond <code>delay</code> call in each loop (without which <a href="https://electronics.stackexchange.com/q/12300/18583">bad things happen</a>). </p>

<h2>Results</h2>

<p>I then calculated the mean execution times of each loop, subtracted 100 milliseconds from each and then plotted the results. </p>

<p><a href="http://github.com/AsheeshR/Arduino-Loop-Analysis/blob/master/Data/Munged/runtime.csv" rel="nofollow noreferrer">http://raw2.github.com/AsheeshR/Arduino-Loop-Analysis/master/Figures/timeplot.png</a></p>

<h1>Conclusion</h1>

<ul>
<li>An un-optimised <code>while(1)</code> loop within <code>void loop</code> is faster than a compiler optimised  <code>void loop</code>. </li>
<li>The time difference between the un-optimized code and default Arduino  optimized code is insignificant <em>practically</em>. You will be better off compiling manually using <code>avr-gcc</code> and using your own optimisation flags rather than depending on the Arduino IDE to help you with it (if you need microsecond optimisations). </li>
</ul>

<hr>

<p><sub>
<strong>NOTE:</strong> The actual time values are not of significance here, the difference between them is. The ~90 microseconds of execution time includes a call to <code>Serial.println</code>, <code>micros</code> and <code>delay</code>.
</sub></p>

<p><sub>
<strong>NOTE2:</strong> This was done using the Arduino IDE and the default compiler flags that it supplies.
</sub></p>

<p><sub>
<strong>NOTE3:</strong> Analysis (plot and calculations) was done using R.
</sub></p>
 136: <p>The part of the code on an ATmega core that does setup() and loop() is at follows:</p>

<pre><code>#include &lt;Arduino.h&gt;

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif

        setup();

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }

        return 0;
}
</code></pre>

<p>Pretty simple, but there is the overhead of the serialEventRun(); in there.</p>

<p>Let's compare two simple sketches:</p>

<pre><code>void setup()
{

}

volatile uint8_t x;

void loop()
{

    x = 1;

}
</code></pre>

<p>and</p>

<pre><code>void setup()
{

}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}
</code></pre>

<p>The x and volatile is just to ensure it isn't optimised out.</p>

<p>In the ASM produced, you get different results:
<img src="https://i.stack.imgur.com/CkIST.png" alt="Comparison of two"></p>

<p>You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.</p>

<p>To generate ASM as above, you need to use a tool called avr-objdump. This is included with avr-gcc. Location varies depending on OS so it is easiest to search for it by name.</p>

<p>avr-objdump can operate on .hex files, but these are missing the original source and comments. If you have just built code, you will have a .elf file that does contain this data. Again, the location of these files varies by OS - the easiest way to locate them is to turn on verbose compilation in preferences and see where the output files are being stored.</p>

<p>Run the command as follows:</p>

<blockquote>
  <p>avr-objdump -S output.elf > asm.txt</p>
</blockquote>

<p>And examine the output in a text editor.</p>
