Benchmarkdotnet vous aide à transformer les méthodes en repères, à suivre leurs performances et à partager des expériences de mesure reproductibles. Ce n'est pas plus difficile que d'écrire des tests unitaires! Sous le capot, il effectue beaucoup de magie qui garantit des résultats fiables et précis grâce au moteur statistique Perfolizer. Benchmarkdotnet vous protège contre les erreurs de comparaison populaires et vous avertit si quelque chose ne va pas avec votre conception de référence ou les mesures obtenues. Les résultats sont présentés sous une forme conviviale qui met en évidence tous les faits importants sur votre expérience. BenchmarkDotnet est déjà adopté par 22000+ projets GitHub, notamment .NET Runtime, .NET Compiler, .NET Performance et bien d'autres.
Il est facile de commencer à écrire des références, consultez l'exemple suivant (la version pastable est ici):
[ SimpleJob ( RuntimeMoniker . Net472 , baseline : true ) ]
[ SimpleJob ( RuntimeMoniker . NetCoreApp30 ) ]
[ SimpleJob ( RuntimeMoniker . NativeAot70 ) ]
[ SimpleJob ( RuntimeMoniker . Mono ) ]
[ RPlotExporter ]
public class Md5VsSha256
{
private SHA256 sha256 = SHA256 . Create ( ) ;
private MD5 md5 = MD5 . Create ( ) ;
private byte [ ] data ;
[ Params ( 1000 , 10000 ) ]
public int N ;
[ GlobalSetup ]
public void Setup ( )
{
data = new byte [ N ] ;
new Random ( 42 ) . NextBytes ( data ) ;
}
[ Benchmark ]
public byte [ ] Sha256 ( ) => sha256 . ComputeHash ( data ) ;
[ Benchmark ]
public byte [ ] Md5 ( ) => md5 . ComputeHash ( data ) ;
}BenchMarkDotNet exécute automatiquement les repères sur tous les temps d'exécution, agrége les mesures et imprime un tableau récapitulatif avec les informations les plus importantes:
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.805 (1809/October2018Update/Redstone5)
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
[ Host ] : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
Net472 : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
NativeAot70 : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT
Mono : Mono 6.4.0 (Visual Studio), X64
| Method | Runtime | N | Mean | Error | StdDev | Ratio |
| ------- | -------------- | ------ | -----------: | ----------: | ----------: | ------: |
| Sha256 | .NET 4.7.2 | 1000 | 7.735 us | 0.1913 us | 0.4034 us | 1.00 |
| Sha256 | .NET Core 3.0 | 1000 | 3.989 us | 0.0796 us | 0.0745 us | 0.50 |
| Sha256 | NativeAOT 7.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
| Sha256 | Mono | 1000 | 13.117 us | 0.2485 us | 0.5019 us | 1.70 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 1000 | 2.872 us | 0.0552 us | 0.0737 us | 1.00 |
| Md5 | .NET Core 3.0 | 1000 | 1.848 us | 0.0348 us | 0.0326 us | 0.64 |
| Md5 | NativeAOT 7.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
| Md5 | Mono | 1000 | 3.574 us | 0.0678 us | 0.0753 us | 1.24 |
| | | | | | | |
| Sha256 | .NET 4.7.2 | 10000 | 74.509 us | 1.5787 us | 4.6052 us | 1.00 |
| Sha256 | .NET Core 3.0 | 10000 | 36.049 us | 0.7151 us | 1.0025 us | 0.49 |
| Sha256 | NativeAOT 7.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
| Sha256 | Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us | 1.58 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 10000 | 17.308 us | 0.3361 us | 0.4250 us | 1.00 |
| Md5 | .NET Core 3.0 | 10000 | 15.726 us | 0.2064 us | 0.1930 us | 0.90 |
| Md5 | NativeAOT 7.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
| Md5 | Mono | 10000 | 30.205 us | 0.5868 us | 0.6522 us | 1.74 |
Les données mesurées peuvent être exportées vers différents formats (MD, HTML, CSV, XML, JSON, etc.), y compris les parcelles:
Runtime pris en charge: .NET 5+, .NET Framework 4.6.1+, .NET Core 3.1+, Mono, Nativeaot
Langages pris en charge: C #, F #, Visual Basic
OS pris en charge: Windows, Linux, macOS
Architectures supportées: x86, x64, arm, arm64, wasm et loongarch64
Benchmarkdotnet a des tonnes de fonctionnalités essentielles dans les enquêtes complètes sur les performances. Quatre aspects définissent la conception de ces caractéristiques: la simplicité , l'automatisation , la fiabilité et la convivialité .
Vous ne devriez pas avoir à être un ingénieur de performance expérimenté si vous souhaitez rédiger des repères. Vous pouvez concevoir des expériences de performance très compliquées dans le style déclaratif en utilisant des API simples.
Par exemple, si vous souhaitez paramétrer votre benchmark, marquez un champ ou une propriété avec [Params(1, 2, 3)] : BenchMarkDotnet énumèrera toutes les valeurs spécifiées et exécutera des repères pour chaque cas. Si vous souhaitez comparer les repères les uns avec les autres, marquez l'une des repères comme la ligne de base via [Benchmark(Baseline = true)] : BenchmarkDotnet le comparera avec tous les autres repères. Si vous souhaitez comparer les performances dans différents environnements, utilisez des travaux. Par exemple, vous pouvez exécuter tous les repères sur .NET Core 3.1 et Mono via [SimpleJob(RuntimeMoniker.NetCoreApp31)] et [SimpleJob(RuntimeMoniker.Mono)] .
Si vous n'aimez pas les attributs, vous pouvez appeler la plupart des API via le style fluide et écrire du code comme ceci:
ManualConfig . CreateEmpty ( ) // A configuration for our benchmarks
. AddJob ( Job . Default // Adding first job
. WithRuntime ( ClrRuntime . Net472 ) // .NET Framework 4.7.2
. WithPlatform ( Platform . X64 ) // Run as x64 application
. WithJit ( Jit . LegacyJit ) // Use LegacyJIT instead of the default RyuJIT
. WithGcServer ( true ) // Use Server GC
) . AddJob ( Job . Default // Adding second job
. AsBaseline ( ) // It will be marked as baseline
. WithEnvironmentVariable ( "Key" , "Value" ) // Setting an environment variable
. WithWarmupCount ( 0 ) // Disable warm-up stage
) ;Si vous préférez l'expérience de ligne de commande, vous pouvez configurer vos repères via les arguments de console dans n'importe quelle application de console (d'autres types d'applications ne sont pas pris en charge).
Des repères fiables incluent toujours beaucoup de code passerelle.
Réfléchissons à ce que vous devez faire dans un cas typique. Tout d'abord, vous devez effectuer une expérience pilote et déterminer le meilleur nombre d'invocations de méthode. Ensuite, vous devez exécuter plusieurs itérations d'échauffement et vous assurer que votre référence a atteint un état d'équilibre. Après cela, vous devez exécuter les principales itérations et calculer certaines statistiques de base. Si vous calculez certaines valeurs dans votre référence, vous devez l'utiliser d'une manière ou d'une autre pour éviter l'élimination du code mort. Si vous utilisez des boucles, vous devez vous soucier de l'effet du déroulement de la boucle sur vos résultats (qui peut dépendre de l'architecture du processeur). Une fois que vous obtenez des résultats, vous devez vérifier certaines propriétés spéciales de la distribution de performances obtenue comme le multimodalité ou les valeurs aberrantes extrêmement élevées. Vous devez également évaluer les frais généraux de votre infrastructure et le déduire de vos résultats. Si vous souhaitez tester plusieurs environnements, vous devez effectuer les mesures dans chacun d'eux et agréger manuellement les résultats.
Si vous écrivez ce code à partir de zéro, il est facile de faire une erreur et de gâcher vos mesures. Notez qu'il s'agit d'une version raccourcie de la liste de contrôle complète que vous devez suivre pendant l'analyse comparative: il y a beaucoup de pièges cachés supplémentaires qui devraient être gérés de manière appropriée. Heureusement, vous ne devriez pas vous en inquiéter car Benchmarkdotnet effectuera ce truc ennuyeux et long pour vous.
De plus, la bibliothèque peut vous aider avec des tâches avancées que vous voudrez peut-être effectuer pendant l'enquête. Par exemple, BenchmarkDotNet peut mesurer les listes de désassemblage de mémoire gérées et natives et d'impression pour vos repères.
Beaucoup de repères manuscrits produisent de mauvais chiffres qui conduisent à des décisions commerciales incorrectes. Benchmarkdotnet vous protège de la plupart des pièges d'analyse comparative et permet d'atteindre une précision de mesure élevée.
Vous ne devez pas vous soucier du nombre parfait d'invocation de la méthode, du nombre d'échauffement et d'itérations réelles: Benchmarkdotnet essaie de choisir les meilleurs paramètres d'analyse d'analyse et d'atteindre un bon compromis entre la prévision de mesure et la durée totale de tous les exécutions de référence. Donc, vous ne devriez pas utiliser de nombres magiques (comme "nous devrions effectuer 100 itérations ici"), la bibliothèque le fera pour vous en fonction des valeurs des mesures statistiques.
Benchmarkdotnet empêche également l'analyse comparative des assemblages non optimisés qui ont été construits à l'aide du mode de débogage car les résultats correspondants ne seront pas fiables. La bibliothèque imprimera un avertissement si vous avez un débogueur ci-joint, si vous utilisez un hyperviseur (HyperV, VMware, VirtualBox) ou si vous avez d'autres problèmes avec l'environnement actuel.
Au cours de plus de 6 ans de développement, nous avons dû faire face à des dizaines de problèmes différents qui peuvent gâcher vos mesures. À l'intérieur de Benchmarkdotnet, il y a beaucoup d'heuristiques, de chèques, de piratages et d'astuces qui vous aident à augmenter la fiabilité des résultats.
L'analyse des données de performance est une activité chronométrée qui nécessite une attention, des connaissances et une expérience. BenchmarkDotNet effectue la partie principale de cette analyse pour vous et présente les résultats dans une forme conviviale.
Après les expériences, vous obtenez un tableau de résumé qui contient de nombreuses données utiles sur les repères exécutés. Par défaut, il ne comprend que les colonnes les plus importantes, mais elles peuvent être facilement personnalisées. L'ensemble de colonnes est adaptatif et dépend de la définition de référence et des valeurs mesurées. Par exemple, si vous marquez l'un des repères comme référence, vous obtiendrez des colonnes supplémentaires qui vous aideront à comparer tous les repères avec la ligne de base. Par défaut, il montre toujours la colonne moyenne, mais si nous avons détecté une grande différence entre la moyenne et les valeurs médianes, les deux colonnes seront présentées.
BenchmarkDotnet essaie de trouver des propriétés inhabituelles de vos distributions de performances et imprime de beaux messages à ce sujet. Par exemple, cela vous avertira en cas de distribution multimodale ou de valeurs aberrantes élevées. Dans ce cas, vous pouvez faire défiler les résultats vers le haut et consulter les histogrammes de style ASCII pour chaque distribution ou générer de beaux graphiques PNG en utilisant [RPlotExporter] .
BenchmarkDotnet ne vous surcharge pas de données; Il montre uniquement les informations essentielles en fonction de vos résultats: il vous permet de garder le résumé petit pour les cas primitifs et de l'étendre uniquement pour des cas compliqués. Bien sûr, vous pouvez demander des statistiques et visualisations supplémentaires manuellement. Si vous ne personnalisez pas la vue de résumé, la présentation par défaut sera autant que possible conviviale. :)
Benchmarkdotnet n'est pas une solution miracle qui rend par magie tous vos benchmarks corrects et analyse les mesures pour vous. Même si vous utilisez cette bibliothèque, vous devez toujours savoir comment concevoir des expériences de référence et comment tirer des conclusions correctes en fonction des données brutes. Si vous voulez en savoir plus sur la méthodologie d'analyse comparative et les bonnes pratiques, il est recommandé de lire un livre d'Andrey Akinshin (The Benchmarkdotnet Project Lead): "Pro .NET Benchmarking". Utilisez ce guide approfondi pour concevoir correctement les repères, mesurer les mesures de performances clés des applications .NET et analyser les résultats. Ce livre présente des dizaines d'études de cas pour vous aider à comprendre des sujets compliqués d'analyse comparative. Vous éviterez les pièges courants, contrôlerez la précision de vos mesures et améliorerez les performances de votre logiciel.
Benchmarkdotnet est déjà une bibliothèque complète stable qui permet d'effectuer une enquête sur les performances au niveau professionnel. Et ça continue d'évoluer! Nous ajoutons de nouvelles fonctionnalités tout le temps, mais nous avons trop de nouvelles idées sympas. Toute aide sera appréciée. Vous pouvez développer de nouvelles fonctionnalités, corriger les bogues, améliorer la documentation ou faire d'autres choses sympas.
Si vous souhaitez contribuer, consultez le guide contributif et les problèmes de grabs réunis. Si vous avez de nouvelles idées ou si vous souhaitez vous plaindre des bogues, n'hésitez pas à créer un nouveau problème. Construisons le meilleur outil pour l'analyse comparative ensemble!
Ce projet a adopté le code de conduite défini par le Contributeur Covenant pour clarifier le comportement attendu dans notre communauté. Pour plus d'informations, consultez le Code de conduite de la fondation .NET.
Benchmarkdotnet est pris en charge par le Fonds logiciel Open Source AWS.