46 opérations .NET mesurées : un agent Copilot a ajouté 16% de latence au premier resolve de DI
L’auteur a testé 46 opérations de DI, configuration, journalisation, cache et EF Core sur six versions de .NET : 30 rounds, avec un runtime fixe. Il a pu remonter deux régressions de 11 RC jusqu’aux commits concernés. La plus importante, un ralentissement ×2,4 du binding de configuration, vient d’une ligne écrite par un humain. La seconde, +16% sur le premier resolve de DI, a été introduite par la PR d’un agent Copilot.
Traité par IA depuis Habr AI ; édité par Hamidun News
Le débat sur la dégradation du code par l’IA repose généralement sur des impressions. L’auteur de cette étude a décidé de mesurer le phénomène. Il a choisi un point de référence : .NET 7 est sorti trois semaines avant ChatGPT et constitue la dernière version écrite avant l’ère des assistants. Depuis mai 2025, un Copilot coding agent intervient dans dotnet/runtime : fin octobre 2026, il avait ouvert 1734 pull requests, dont 1207 avaient été fusionnées.
Méthode de mesure
Le runtime a été fixé à .NET 10.0.11. Seuls les packages NuGet Microsoft.Extensions.*, des versions 6 à 11, et EF Core, des versions 6 à 10, variaient. Les gains liés au JIT et au GC n’entrent donc pas dans les résultats. Au total : 46 opérations, 30 rounds, chaque scénario exécuté dans un processus distinct sur des cœurs dédiés, avec un ordre des versions aléatoire. Une opération n’est déclarée « plus rapide » ou « plus lente » que si l’intégralité de l’intervalle de confiance à 95% se situe au-delà du seuil de 5%.
Le premier bilan est contrasté. Pour la version 10.0 face à 7.0 : 9 opérations sont plus rapides, 13 plus lentes et 10 restent dans la marge de bruit. Le code déjà chaud a gagné 14–35% : LoggerMessage.Define passe de 377 à 244 ns, et DetectChanges sur 10 milliers d’entités de 6,1 à 4,3 ms. En revanche, les premiers appels et la création d’objets coûtent 39–64% plus cher : la première requête EF passe de 996 à 1162 ms. Le compromis est favorable à un service de longue durée, mais pas aux processus courts ni au démarrage à froid.
La majorité des écarts, 19 sur 46, apparaît lors du passage à 8.0, première version publiée après ChatGPT. Mais l’auteur le précise honnêtement : les mesures montrent ce qui a changé, pas pourquoi. Cette étape inclut également le changement de cible de compilation, de net7.0 à net8.0.
Où l’agent est intervenu
L’historique Git entre v7.0.20 et v10.0.14 contient 113 commits liés à DI et au cache, sans aucun commit de l’agent. Celui-ci apparaît dans la fenêtre menant à 11 RC : il est par exemple à l’origine de 3 des 11 modifications apportées aux méthodes critiques de DI et du cache. Précision importante : un commit de l’agent signifie que « la PR a été ouverte par l’agent », et non qu’elle a été « écrite sans intervention humaine ». Toutes les PR sont relues par des humains, tandis que l’éventuelle utilisation d’un assistant dans l’IDE n’apparaît pas du tout dans Git.
Deux régressions dans 11 RC
La plus importante concerne le binding d’un POCO de 50 champs, passé de 61 à 145 µs, et IOptionsSnapshot dans un nouveau scope, passé de 52 à 136 µs. La cause tient à une ligne de la PR #126396, consacrée à l’attribut [ConfigurationIgnore] : property.IsDefined(...)
est exécuté pour chaque propriété à chaque binding. L’auteur a compilé le binder depuis les sources, remplacé l’expression par false et substitué une seule DLL : le temps est revenu à 60 µs. L’essentiel du coût vient de l’overload dont le paramètre inherit vaut true par défaut.
La PR a été écrite par un humain. Les mainteneurs ont reconnu la régression, tout en rappelant que le générateur de code source est recommandé pour les chemins critiques. Un correctif pour 11.
0 a été évoqué, mais il n’est pas garanti : l’issue est rattachée au milestone 12.0.0.
La seconde régression est plus modeste : le premier resolve de DI a augmenté de 16,5%. Un bisect entre les commits a identifié la PR #124331 de l’agent, qui corrige un deadlock lié aux dépendances cycliques passant par des fabriques. VisitRootCache maintient désormais un HashSet ThreadStatic, ce qui coûte environ 0,9 µs lors du premier resolve. Le seul retour en arrière de cette PR ramène le temps au niveau de 10.0. Le commit n’affecte ni les singleton et scoped déjà chauds, ni la construction du provider. L’auteur juge ce coût raisonnable en contrepartie de la correction d’un véritable deadlock.
Que faire
- Si vous utilisez 11 RC et effectuez beaucoup de bindings de configuration, activez le générateur de code source (EnableConfigurationBindingGenerator) : 12 µs, contre 29 µs dans 10.0.
- Là où une actualisation pendant la requête n’est pas nécessaire, remplacez IOptionsSnapshot par IOptionsMonitor.
- Surveillez le démarrage à froid : son coût a augmenté à plusieurs endroits.
Limites : il s’agit d’une release candidate, les mesures ont été réalisées sur un seul ordinateur portable et le scénario principal utilise un build 11.0 sur le runtime .NET 10. La conclusion sur l’IA reste modeste : aucune des deux régressions ne prouve que l’IA dégrade le code. L’une a été introduite par un humain ; l’autre par un agent, en contrepartie de la correction d’un véritable bug. La méthode, qui détecte les régressions par des mesures et un bisect, vaut en revanche davantage que tous les débats.
- 12 nov. 2026Jensen Huang quitte son poste de PDG de Nvidia : l’entreprise perd 1 400 milliards de dollars en deux semaines
- 12 nov. 2026Huit pays, OpenAI et Anthropic promettent un « interrupteur d'arrêt » pour les modèles d'IA, mais sans échéances ni sanctions
- 12 nov. 2026Microsoft brevette l'entraînement d'IA sur des cartes graphiques inactives, avec rémunération
- 12 nov. 2026Un chercheur, un ordinateur portable et Claude : plus de 100 failles trouvées dans le code de sites gouvernementaux britanniques
Questions clés sur cet article
Que sait-on sur Méthode de mesure ?
Le runtime a été fixé à .NET 10.0.11. Seuls les packages NuGet Microsoft.Extensions., des versions 6 à 11, et EF Core, des versions 6 à 10, variaient. Les gains liés au JIT et au GC n’entrent donc pas dans les résultats. Au total : 46 opérations, 30 rounds, chaque scénario exécuté dans un processus distinct sur des cœurs dédiés, avec un ordre des versions aléatoire.
Que sait-on sur Où l’agent est intervenu ?
L’historique Git entre v7.0.20 et v10.0.14 contient 113 commits liés à DI et au cache, sans aucun commit de l’agent. Celui-ci apparaît dans la fenêtre menant à 11 RC : il est par exemple à l’origine de 3 des 11 modifications apportées aux méthodes critiques de DI et du cache. Précision importante : un commit de l’agent signifie que « la PR a été ouverte par l’agent », et non qu’elle a été « écrite sans intervention humaine ».
Que sait-on sur Deux régressions dans 11 RC ?
La plus importante concerne le binding d’un POCO de 50 champs, passé de 61 à 145 µs, et IOptionsSnapshot dans un nouveau scope, passé de 52 à 136 µs. La cause tient à une ligne de la PR #126396, consacrée à l’attribut [ConfigurationIgnore] : property.IsDefined(...) est exécuté pour chaque propriété à chaque binding. L’auteur a compilé le binder depuis les sources, remplacé l’expression par false et substitué une seule DLL : le temps est revenu à 60 µs.
Build & Ship Production AI Agents Without Boilerplate Code
Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.
L'essentiel de l'IA — une fois par semaine
Sept actus qui ont vraiment compté, choisies à la main. Sans bruit ni communiqués.
C'est fait ! Vérifiez votre boîte mail pour la confirmation.