Il modo più efficiente per testare il tipo di oggetto
Domanda
Ho valori memorizzati come stringhe in a DataTable
dove ogni valore potrebbe realmente rappresentare un int
, double
, O string
(sono stati tutti convertiti in stringhe durante un processo di importazione da un'origine dati esterna).Devo testare e vedere di che tipo è realmente ciascun valore.
Cos'è più efficiente per l'applicazione (o non c'è alcuna differenza pratica)?
- Prova a convertire in
int
(poidouble
).Se la conversione funziona, il returntrue
.Se viene lanciata un'eccezione, ritornafalse
. - Espressioni regolari progettate per corrispondere al modello di an
int
Odouble
- Qualche altro metodo?
Soluzione
Utilizzerei double.TryParse, presenta vantaggi in termini di prestazioni.
Altri suggerimenti
Direi che non preoccuparti così tanto di tali micro-prestazioni.È molto meglio semplicemente far funzionare qualcosa e poi renderlo il più chiaro, conciso e facile da leggere possibile.La cosa peggiore che puoi fare è sacrificare la leggibilità per una quantità insignificante di prestazioni.
Alla fine, il modo migliore per gestire i problemi di prestazioni è salvarli per quando si dispone di dati che indicano che esiste un problema di prestazioni effettivo...altrimenti passerai molto tempo alla micro-ottimizzazione e causerai effettivamente costi di manutenzione più elevati per il futuro.
Se ritieni che questa situazione di analisi sia davvero il collo di bottiglia nella tua applicazione, ALLORA è il momento di provare a capire qual è il modo più veloce per risolvere il problema.Penso che Jeff (e molti altri) abbiano scritto molto sul blog su questo genere di cose.
Otterrai risultati diversi per i diversi metodi a seconda che compili con le ottimizzazioni attivate.Fondamentalmente hai alcune opzioni:
object o;
//checking with is
o is int
//check type
o.GetType() != typeof( int )
//cast and catch exception
try{ int j = (int) o; }
catch {}
//use the tryparse
int.TryParse( Convert.ToString( o ), out j )
Puoi facilmente configurare un'app console che prova ciascuna di queste 10.000 volte e restituisce le durate per ciascuna (prova quando o è un int e quando è qualcos'altro).
IL try-catch
è il più veloce se l'oggetto contiene un int e di gran lunga il più lento se non lo contiene (anche più lento di GetType
). int.TryParse
è piuttosto veloce se hai una stringa, ma se hai un oggetto sconosciuto è più lento.
È interessante notare che con .Net 3.5 e le ottimizzazioni attivate o is int
il controllo richiede lo stesso tempo di try-catch
quando o in realtà è un int. o is int
è solo leggermente più lento se o effettivamente è qualcos'altro.
Fastidiosamente FxCop genererà avvisi se fai qualcosa del tipo:
if( o is int )
int j = (int) o;
Ma penso che sia un bug in FxCop: non sa che int è un tipo di valore e ti consiglia di usarlo o as int
Invece.
Se il tuo input è sempre una stringa int.TryParse
è meglio, altrimenti il is
l'operatore è il più veloce.
Dato che hai una stringa, valuterei se devi sapere che è un int, piuttosto che un double.Se int.TryParse
passa allora così passerà double.TryParse
quindi potresti dimezzare il numero di controlli: restituire double o string e floor i double quando ti aspetti un int.
Il problema che hai è che potrebbero esserci situazioni in cui la risposta potrebbe essere di tutti e tre i tipi.
3 potrebbe essere un int, un double o una stringa!
Dipende da cosa stai cercando di fare e da quanto sia importante che siano di un tipo particolare.Potrebbe essere meglio lasciarli così come sono il più a lungo possibile o, in alternativa, creare un metodo per contrassegnarli ciascuno (se hai il controllo della fonte della stringa originale).
Personalmente utilizzerei int.tryparse, quindi double.tryparse.Le prestazioni con questi metodi sono piuttosto veloci.Entrambi restituiscono un valore booleano.Se entrambi falliscono, hai una stringa, in base a come hai definito i tuoi dati.