It depends. Serial data is received into, or sent from, buffers (one for sending and one for receiving). If you have a processor with 1024 bytes of RAM or more, then the buffer size is 64 bytes, otherwise it is 16 bytes. (See the HardwareSerial.h file in your distribution).
If the buffer fills up when sending, it will block (that is, the code will wait for the buffer to empty). If it fill up when receiving the extra bytes will be discarded.
If the buffer does not fill up, then the baud rate will not affect performance. That is because data is sent, or received, by an interrupt service routine, in the background.
As a rule of thumb, you can expect data to be sent or received at the baud rate divided by 10. That is because each byte is 8 bits, plus a start and a stop bit (10 bits in total).
So, for example, at 9600 baud you can send 960 characters per second. If you are sending something simple, like a temperature which is 20 bytes, every second, then the baud rate won't affect performance at all. If you are trying to send thousands of bytes per second, it will affect performance, because the Serial.println
will probably block once the buffer fills up.
For instance, when I call Serial.prinlnt("test"), how does that get to the serial line?
If the buffer is not full, then "t" "e" "s" "t" are copied into the buffer, and the code returns immediately. If the buffer is full then it waits for it to become not-full.
As an efficiency measure, if you are sending a single byte, and the buffer is empty, then the byte is placed in the hardware register immediately (saving a small amount of time). In this case, if the buffer was empty, "t" would be sent immediately, and "est" would be sent afterwards, as a "byte has been sent" interrupt is raised.1
This is described in the code comments:
size_t HardwareSerial::write(uint8_t c)
{
_written = true;
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
*_udr = c;
sbi(*_ucsra, TXC0);
return 1;
}
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
while (i == _tx_buffer_tail) {
if (bit_is_clear(SREG, SREG_I)) {
// Interrupts are disabled, so we'll have to poll the data
// register empty flag ourselves. If it is set, pretend an
// interrupt has happened and call the handler to free up
// space for us.
if(bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
} else {
// nop, the interrupt handler will free up space for us
}
}
_tx_buffer[_tx_buffer_head] = c;
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
return 1;
}
Notice that the byte is not placed in the buffer at all if it is empty, and nothing is being sent.
For more information see my question and answer about serial processing.
- Strictly speaking, after discussing this in the comments with Majenko, the interrupt that is raised is really that the hardware "send" buffer is empty. When the send buffer empties then the interrupt is called so that the interrupt code can put a new byte into it.