Why is Serial.write() slower than memcpy()?
If you take a look into the implementation:

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 (&gt;
  // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
  if (_tx_buffer_head == _tx_buffer_tail &amp;&amp; bit_is_set(*_ucsra, UDRE0)) {
    // If TXC is cleared before writing UDR and the previous byte
    // completes before writing to UDR, TXC will be set but a byte
    // is still being transmitted causing flush() to return too soon.
    // So writing UDR must happen first.
    // Writing UDR and clearing TC must be done atomically, otherwise
    // interrupts might delay the TXC clear so the byte written to UDR
    // is transmitted (setting TXC) before clearing TXC. Then TXC will
    // be cleared when no bytes are left, causing flush() to hang
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      *_udr = c;
#ifdef MPCM0
      *_ucsra = ((*_ucsra) &amp; ((1 &lt;&lt; U2X0) | (1 &lt;&lt; MPCM0))) | (1 &lt;&lt; TXC0);
#else
      *_ucsra = ((*_ucsra) &amp; ((1 &lt;&lt; U2X0) | (1 &lt;&lt; TXC0)));
#endif
    }
    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;

  // make atomic to prevent execution of ISR between setting the
  // head pointer and setting the interrupt flag resulting in buffer
  // retransmission
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    _tx_buffer_head = i;
    sbi(*_ucsrb, UDRIE0);
  }

  return 1;
}


It basically answers all the questions.

If the buffer is empty and it's not sending anything, it'll send the character directly so it's synchronous (but sending the character will be much faster than overhead of function callbacks and so)

No, you cannot use memcpy, as it just replaces buffer, but it does nothing else, like actually start the data register ready interrupt nor proper setting of head/tail counters (it's round buffer, so there can be scenario you'll overwrite something outside of buffer)

And write function is called for each character separately (all other specialisation of write are using this one)

Also if the buffer is full, it'll wait until there is a space for another character.