dipende, se si legge o si scrive un carattere solo hai ragione altrimenti la fread e fwrite è più veloce perchè utilizza blocchi di memoria di dimensioni adatti al sistema su cui opera per minimizzare il numero di chiamate di sistema che sono le più costose.
Per esempio guarda questa implementazione di getchar
codice:
int getchar () {

  static char buffer[BUFSIZ];
  static char * ptr_buf = buffer;
  static n_char = 0;

  // verifica se il buffer è vuoto
  if ( !n_char ) {
    // legge dallo stdin <0>
    n_char = read (0, buffer, sizeof ( buffer ) );
    // riposiziona il puntatore all'inizio del buffer
    ptr_buf = buffer;
  }
  return (--n_char >= 0) ? (unsigned char) *ptr_buf++ : EOF;
 
}
viene eseguita una unica chiamata di sistema per tutta la dimensione di buffer (BUFSIZE è definito in syscalls.h) e poi si svuota via via il buffer.
ciao
sergio