English
Français

Blog of Denis VOITURON

for a better .NET world

C# TryParse Vs Try Catch

Posted on 2022-09-02

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

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
|---------|------------------|-------------|-------------|

Langues

EnglishEnglish
FrenchFrançais

Suivez-moi

Articles récents