Domanda

La mia applicazione legge un file Excel utilizzando VSTO e aggiunge i dati letti a una StringDictionary. Aggiunge solo i dati che sono numeri con poche cifre (1000 1000,2 1000,34 - virgola è un delimitatore in standard russi).

Cosa c'è di meglio per verificare se la stringa corrente è un numero appropriato?

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

o

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

È necessario utilizzare StringDictionary invece di Dictionary<string, double> a causa dei problemi seguente algoritmo di analisi.

Le mie domande: Da che parte è più veloce? Che è più sicuro?

Ed è meglio chiamare Convert.ToDouble(object) o Convert.ToDouble(string)?

È stato utile?

Soluzione

Ho fatto una prova non scientifica rapido in modalità di rilascio. Ho usato due ingressi:. "2,34,523 mila" e "badinput" in entrambi i metodi e iterato 1.000.000 volte

I valori validi:

Double.TryParse = 646ms
Convert.ToDouble = 662 ms

Non molto diverso, come previsto. Per tutti gli effetti, per l'input validi, questi sono gli stessi.

Input non valido:

Double.TryParse = 612ms
Convert.ToDouble = ..

Beh .. è stato in esecuzione per un lungo periodo di tempo. Ho reran l'intera cosa con 1.000 iterazioni e Convert.ToDouble con prese input non validi 8,3 secondi. Una media di fuori, ci vorrebbero più di 2 ore. Non mi importa come base il test è, nel caso di ingresso valido, ad eccezione innalzamento del Convert.ToDouble rovinerà le vostre prestazioni.

Quindi, ecco un altro voto per TryParse con alcuni numeri una copia di backup.

Altri suggerimenti

Per cominciare, mi piacerebbe utilizzare double.Parse piuttosto che Convert.ToDouble in primo luogo.

Per quanto riguarda se è necessario utilizzare Parse o TryParse: si può procedere se non c'è dati di input cattivi, o è che una condizione davvero eccezionale? Se è eccezionale, utilizzare Parse e farlo saltare in aria se l'ingresso è male. Se ci si aspetta e può essere gestito in modo pulito, usare TryParse.

Le linee guida di progettazione .NET Framework consiglia di utilizzare i metodi di prova. Evitare le eccezioni di solito è una buona idea.

Convert.ToDouble(object) farà ((IConvertible) object).ToDouble(null);

che chiamerà Convert.ToDouble(string, null)

Quindi, è più veloce di chiamare la versione stringa.

Tuttavia, la versione stringa fa proprio questo:

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

Quindi è più veloce a che fare direttamente il double.Parse.

Se non si sta per essere gestire l'eccezione andare con TryParse. TryParse è più veloce perché non ha a che fare con l'intero stack eccezione.

Io in genere cerco di evitare la classe Convert (che significa: io non lo uso) perché lo trovo molto confuso: il codice dà anche alcuni suggerimenti su ciò che accade esattamente qui dal Convert permette un sacco di semanticamente molto diverse conversioni verificare con lo stesso codice. Questo rende difficile da controllare per il programmatore che cosa esattamente sta accadendo.

Il mio consiglio, quindi, è di non usare questa classe. Non è davvero necessario o (fatta eccezione per la formattazione binaria di un numero, perché il metodo ToString normale delle classi di numero non offre un metodo appropriato per fare questo).

Se non sei sicuro al 100% di ingressi, che è raramente il caso, è necessario utilizzare Double.TryParse.

Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.

La velocità del parse diventa secondario quando si lancia un'eccezione, perché non c'è molto più lento di un'eccezione.

Un sacco di odio per la classe Convert qui ... Giusto per bilanciare un po ', v'è un vantaggio per Convert - se si è consegnato un oggetto,

Convert.ToDouble(o);

può semplicemente restituire il valore facilmente se o è già un doppio (o un int o qualsiasi cosa facilmente colabile).

utilizzando Double.Parse o Double.TryParse è grande se è già in possesso di una stringa, ma

Double.Parse(o.ToString());

deve andare make la stringa da analizzare prima e seconda del vostro ingresso che potrebbe essere più costoso.

Double.TryParse IMO.

E 'più facile per voi per gestire, saprete esattamente dove si è verificato l'errore.

Poi si può trattare con esso come si vede in forma, se restituisce false (cioè non in grado di convertire).

ho sempre preferito utilizzando i metodi TryParse() perché sta andando a sputare indietro successo o il fallimento di convertire, senza doversi preoccupare di eccezioni.

Personalmente, trovo il metodo TryParse più facile da leggere, quale ci troveremo da utilizzare dipende dal vostro caso d'uso: se errori possono essere gestiti localmente errori che ti aspetti e un bool da TryParse è buono, altrimenti si potrebbe desiderare di lasciare che le eccezioni volano.

mi aspetterei il TryParse per essere più veloce, in quanto anche evita il sovraccarico di gestione delle eccezioni. Ma utilizzare uno strumento di riferimento, come Jon Skeet MINIBENCH per confrontare le varie possibilità.

Questa è una vecchia questione interessante. Sto aggiungendo una risposta perché nessuno ha notato un paio di cose con la domanda originale.

che è più veloce: Convert.ToDouble o Double.TryParse? Che è più sicuro:? Convert.ToDouble o Double.TryParse

ho intenzione di rispondere a entrambe queste domande (io aggiornare la risposta più tardi), nel dettaglio, ma prima:

Per motivi di sicurezza, la cosa tutti programmatore perso in questa domanda è la linea (sottolineatura mia):

  

Si aggiunge solo i dati che sono numeri con poche cifre (1000 1000,2 1000,34 - virgola è un delimitatore in standard russi ).

Seguita da questo esempio di codice:

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

La cosa interessante qui è che se i fogli di calcolo sono in formato numero russo, ma Excel non ha digitato correttamente i campi di cellule, qual è la corretta interpretazione dei valori provenienti da Excel?

Qui è un'altra cosa interessante circa i due esempi, per quanto riguarda la velocità:

catch (InvalidCastException)
{
    // is not a number
}

Questa è probabile che a generare MSIL che assomiglia a questo:

catch [mscorlib]System.InvalidCastException 
{
  IL_0023:  stloc.0
  IL_0024:  nop
  IL_0025:  ldloc.0
  IL_0026:  nop
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  leave.s    IL_002f
}  // end handler
IL_002f: nop
IL_0030: return

In questo senso, probabilmente possiamo confrontare il numero totale di istruzioni MSIL svolte da ciascun programma -. Ne riparleremo più avanti come aggiorno questo post

Credo codice dovrebbe essere corretta, chiara e veloce ... In questo ordine!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top