EDIT: Ora che ci hai fornito un po 'di contesto:
Cercando di riprodurre questo, non sono riuscito a trovare un collo di bottiglia nel string.Length
a tutti. L'unico modo per renderlo più veloce era di commentare sia il test sia il corpo del blocco if, il che non è corretto. Solo commentare la condizione ha rallentato le cose, ovvero copiare incondizionatamente il riferimento è stato più lento rispetto alla verifica della condizione.
Come è stato sottolineato, l'utilizzo del sovraccarico di string.Split
che rimuove le voci vuote per voi è la vera ottimizzazione dell'assassino.
Puoi andare oltre, evitando di creare un nuovo array di caratteri con solo uno spazio in ogni momento. Passerai sempre la stessa cosa in modo efficace, quindi perché non approfittarne?
Gli array vuoti sono effettivamente immutabili. È possibile ottimizzare il caso null/vuoto restituendo sempre la stessa cosa.
Il codice ottimizzato diventa:
private static readonly char[] Delimiters = " ".ToCharArray();
private static readonly string[] EmptyArray = new string[0];
public static string[] SplitOnMultiSpaces(string text)
{
if (string.IsNullOrEmpty(text))
{
return EmptyArray;
}
return text.Split(Delimiters, StringSplitOptions.RemoveEmptyEntries);
}
String.Length
assolutamente fa non contare le lettere nella stringa. Il valore è archiviato come un campo - anche se mi sembra di ricordare che il bit più in alto di quel campo è usato per ricordare se tutti i caratteri sono ASCII (o comunque usati per essere abilitati) per abilitare altre ottimizzazioni. Quindi l'accesso alla proprietà potrebbe aver bisogno di fare una maschera di bit, ma sarà comunque O (1) e mi aspetto che anche il JIT lo inline. (E 'implementato come un extern
, ma si spera che non pregiudicherebbe il JIT in questo caso -. Ho il sospetto che sia un'operazione abbastanza comune per potenzialmente avere un supporto speciale)
Se sai già che la stringa non è nullo, quindi il test esistente di
if (s.Length != 0)
è il modo migliore per andare se siete alla ricerca di prestazioni pure IMO. Personalmente, nella maggior parte dei casi mi piacerebbe scrivere:
if (s != "")
per renderlo più chiaro che non siamo tanto interessati alla lunghezza come un valore come se questa è la stringa vuota. Sarà leggermente più lento del test di lunghezza, ma credo sia più chiaro. Come sempre, sceglierei il codice più chiaro finché non avremo dati di benchmark/profiling per indicare che questo veramente è un collo di bottiglia. So che la tua domanda riguarda esplicitamente la ricerca del test più efficiente, ma ho pensato di parlarne comunque. Avete prove che questo è un collo di bottiglia?
EDIT: Giusto per motivare più chiare per il mio suggerimento di non utilizzando string.IsNullOrEmpty
: una chiamata a quel metodo mi suggerisce che il chiamante è esplicitamente cercando di trattare il caso in cui la variabile è nulla, altrimenti si wouldn' L'ho menzionato. Se a questo punto del codice conta come un bug se la variabile è null, allora non dovresti provare a gestirla come un caso normale.
In questa situazione, il controllo è in realtà Length
meglio in un modo che il test di ineguaglianza ho suggerito: agisce come asserzione implicita che la variabile non è nullo. Se si verifica un bug e è null, il test genererà un'eccezione e il bug verrà rilevato in anticipo. Se si utilizza il test di uguaglianza, considererà null come diverso dalla stringa vuota, quindi entrerà nel corpo della propria istruzione "if". Se si utilizza string.IsNullOrEmpty
, verrà considerato nulla come vuoto, quindi non entrerà nel blocco.
Il problema del furto che affronti è molto probabile risolto altrove! Hai il profilo e scopri che il collo di bottiglia è davvero qui? –
Per curiosità quale versione del framework stai prendendo di mira? –
** NOTA ** per altri aspiranti-rispondenti: Eric ha pubblicato una risposta che chiarisce la sua domanda (kinda) sotto .... –