C# TryParse Vs Try Catch
Cet article analyse les performances C# entre l’utilisation de TryParse et de Try Catch. Il arrive fréquemment que l’on recoive des données, dont le format est suspect, et qu’il faut convertir vers un type de données bien précis. Pour cela, le développeur utilise fréquemment TryParse ou Try Catch. Mais quelle est la meilleure solution ?
Chacun a ses avantages et ses inconvénients en fonction du contexte. Je pense que la plupart des développeurs suggéreraient
- l’approche Try Catch permet d’obtenir plus d’informations sur l’erreur de conversion.
- l’utilisation de TryParse si vous ne vous souciez pas de savoir pourquoi quelque chose échoue.
Personnellement, je préconise d’utiliser TryParse dans tous les cas et de tracer les données erronées lorsque le résultat de cette méthode revient avec la valeur False.
Plus précisément, en effectuant un Benchmark des conversions suivantes, nous pouvons constater que le TryParse est toujours plus rapide. La conversion peut être plusieurs centaines de fois plus lente, lorsque beaucoup de données sont erronnées et enclenchent des exceptions.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
public class TryCatchOrTryParse
{
private static Random random = new Random();
private string _myDate = "";
private string _myNumber = "";
public TryCatchOrTryParse()
{
PercentageWrongValues = 80; // 5 or 80
if (random.Next(0, 100) > PercentageWrongValues)
{
_myNumber = RandomString("1234567890", 6);
_myDate = $"{random.Next(1000, 9999)}-01-12";
}
else
{
_myNumber = RandomString("ABCDEFGHI", 6);
_myDate = $"{random.Next(1000, 9999)}-01-32";
}
string RandomString(string chars, int length)
{
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
}
public int PercentageWrongValues { get; set; }
[Benchmark]
public int? Int32_TryParse()
{
bool ok = Int32.TryParse(_myNumber, out Int32 result);
return ok ? result : null;
}
[Benchmark]
public int? Int32_TryCatch()
{
try
{
return Convert.ToInt32(_myNumber);
}
catch
{
return null;
}
}
[Benchmark]
public DateTime? DateTime_TryParse()
{
bool ok = DateTime.TryParse(_myDate, out DateTime result);
return ok ? result : null;
}
[Benchmark]
public DateTime? DateTime_TryCatch()
{
try
{
return Convert.ToDateTime(_myDate);
}
catch
{
return null;
}
}
}
Le tableau suivant affiche la moyenne du temps d’exécution de ces méthodes, grâce à la librairie de benchmark BenchmarkDotNet.
La première moyenne se base sur l’hypothese que 5% des données converties sont erronées. La seconde moyenne suppose que 80% des données converties sont erronées.
BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22000.856/21H2)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.400
[Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT AVX2
DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT AVX2
| % Wrong | Method | TryParse | Try Catch |
|---------|------------------|-------------|-------------|
| 5% | Int32 | 16.34 ns | 17.41 ns | => x 1.06
| 5% | Date | 209.44 ns | 219.68 ns | => x 1.04
|---------|------------------|-------------|-------------|
| 80% | Int32 | 19.02 ns | 9289.64 ns | => x 488.41
| 80% | Date | 195.15 ns | 8304.45 ns | => x 45.55
|---------|------------------|-------------|-------------|