Nella maggior parte dei casi non devi sacrificare la leggibilità per avere un codice ben funzionante.
È tutta una questione di scelta delle strutture dati corrette e dell'algoritmo per il lavoro. La maggior parte dei casi con codice scarsamente performante sono causati dallo sviluppatore che non comprende le strutture che utilizza.
Un buon esempio di un simile comportamento che vedo comunemente è l'uso eccessivo di List in C # e del vettore in C ++ - per molti programmatori queste due strutture dati sono l'unico modo per esprimere "un mucchio di T" o una "collezione" di T ". Dove alcune altre strutture come le liste collegate o gli alberi che sono contenuti in classi ben astratte e opportunamente implementate farebbero la stessa cosa ma con una minore ampiezza di complessità.
Un altro esempio è l'utilizzo di enormi istruzioni sui blocchi / sezioni critiche di grandi dimensioni, dove in realtà bloccare / proteggere solo una o due righe di codice sarebbe più che sufficiente.
Ancora un altro esempio che ho dovuto affrontare la scorsa settimana quando ho dovuto ottimizzare un po 'di codice era, quando il codice originale aveva bisogno di importare circa 5000 file xml nel database, ma doveva solo importare un campo di esso contenuto in i primi 100 byte del file. Invece di usare XmlReader e solo leggere fino a raggiungere quel campo, quel codice stava caricando l'intero xml in XmlDocument e chiamando X-Path su di esso. Il tempo di esecuzione è stato ridotto a circa 1/30 del codice originale e direi che quest'ultima versione era più leggibile e mantenibile.
Scrivere un codice più performante è solo una questione di comprensione degli algoritmi fondamentali e delle strutture dati dietro le astrazioni implementate nei framework forniti. È molto raro (e intendo davvero raro) vedere un codice che ha bisogno di codice altamente illeggibile (come l'assembly) per fare lo stesso lavoro ma più velocemente.