Nœuds visités : 11. Nombre de comparaisons : inchangé.
Lors de tests locaux en septembre 2026, le prototype de découverte affichait toujours les mêmes compteurs : avec 32 Agents comme avec 512. La requête se propageait au maximum sur deux sauts voisins. Les chiffres semblaient conformes aux attentes.
Mais le 95e percentile de latence passait de 5.66 à 47.64 millisecondes. Un réseau 16 fois plus grand rendait la requête plus de huit fois plus lente.
Cette contradiction pointait vers du travail réalisé hors du compteur de visites.
Avant le départ, le système avait déjà parcouru tout le réseau
Chaque Agent du prototype conserve un signal de découverte et quelques voisins. À chaque nœud, la requête doit évaluer si les environs contiennent encore des objets intéressants. Le système construit donc un résumé du voisinage, regroupant le signal public du nœud et ceux de ses voisins à un saut.
Sur un plan de ville, la requête ne veut parcourir que quelques rues ; le résumé est le panneau d’orientation au carrefour qui l’aide à choisir sa direction.
La première implémentation procédait commodément : reconstruire les panneaux de tous les nœuds au début de chaque requête, puis la laisser partir.
# Structure simplifiée du chemin initial
adverts = build_all_neighborhood_summaries(network)
return walk_local_routes(request, adverts)
La seconde ligne ne parcourt effectivement que des chemins locaux. La première a déjà balayé tout le réseau.
Les compteurs couvraient principalement propagation et comparaisons. Ils signalaient fidèlement « 11 nœuds visités », soit le travail de propagation. La reconstruction globale précédait cette phase, consommait du temps et croissait avec le réseau sans apparaître dans ces comptes.
Les systèmes de données connaissent bien ce phénomène. Une base peut parcourir de nombreuses lignes pour en retourner très peu. Une requête avec LIMIT peut payer d’abord le tri ou la construction d’un index. La documentation EXPLAIN de PostgreSQL distingue lignes produites, coût de démarrage et coût total. Chaque mesure doit être lue avec son périmètre.
Le problème du prototype était désormais précis : le travail économisé par la visite locale était réalisé avant même son commencement.
Construire le résumé au moment où il devient nécessaire
Nous avons remplacé la construction globale par une construction par nœud. Lorsqu’une requête atteint une arête et doit examiner son voisinage, elle construit ce résumé. Si la même requête synchrone le réutilise, elle reprend le résultat déjà calculé.
# Structure simplifiée du chemin révisé
adverts = {}
def summary_for(edge_id):
if edge_id not in adverts:
adverts[edge_id] = build_one_neighborhood_summary(edge_id)
return adverts[edge_id]
return walk_local_routes(request, summary_for)
adverts ne vit que le temps d’une requête. La suivante relit les nœuds et connexions actuels : modifications, arrivées et départs se reflètent naturellement dans les nouveaux résumés. Cette simplicité est volontaire. Le prototype fonctionne de manière synchrone, sans modification concurrente du réseau pendant une découverte. La réutilisation interne capte l’essentiel du gain sans invalidation de cache entre requêtes.
La construction de tous les résumés reste utile pour le diagnostic ou l’export d’un instantané du réseau. Elle cesse simplement d’être un passage obligé des requêtes ordinaires.
Deux compteurs ont été ajoutés : nombre de résumés construits et nombre de contributeurs lus pour ces résumés. Le compteur de visites reste présent ; la préparation entre désormais dans le champ observable.
Même charge, courbe de latence plus plate
La comparaison conserve machine, topologie, requêtes et configuration. Chaque taille reçoit 12 requêtes de découverte. Les connexions forment un anneau bidirectionnel fixe, avec des voisins aux décalages 1 et 3 et une propagation limitée à deux sauts. Voici les résultats historiques de ce bref test local construit.
| Agents dans le réseau | p95 avant | p95 après |
|---|---|---|
| 32 | 5.66 ms | 4.28 ms |
| 128 | 13.21 ms | 4.91 ms |
| 512 | 47.64 ms | 5.15 ms |
Figure 1 : comparaison historique avant/après sur une même charge. L’axe horizontal présente les trois tailles testées ; les traits guident la lecture. Chaque point est le p95 de 12 requêtes.
À 512 Agents, le débit passe d’environ 22 à environ 209 requêtes par seconde. Chaque requête visite toujours 11 Agents, mais ne construit plus que 10 résumés et examine 50 contributeurs. Ces deux nombres restent identiques aux trois tailles.
L’analyse appariée a vérifié nombres de candidats, de transmissions, de visites et anciens compteurs de ressources : ils restent identiques dans les enregistrements. L’explication est donc précise : du prétraitement inutilisé a été supprimé. La nouvelle courbe temporelle et les nouveaux compteurs se corroborent.
Ce résultat concerne la machine unique, l’exécution synchrone et la topologie construite de l’époque. Avec seulement 12 requêtes par groupe, le p95 est une statistique à interpolation linéaire sur un petit échantillon. La latence de queue en production dépend aussi de la concurrence, du réseau et des changements de données. L’apport principal est d’avoir identifié et éliminé un travail préalable qui croissait effectivement avec le réseau entier.
Un algorithme local a besoin d’un chemin de requête local
Un algorithme peut être sobre dans sa boucle principale et parcourir toutes les données pendant initialisation, sérialisation, maintenance d’index ou nettoyage. Ici, l’oubli concernait les résumés ; les nouveaux compteurs les intègrent au coût de la requête.
Un petit essai peut être reproduit dans votre système : garder fixes les objets réellement nécessaires à la requête, augmenter les objets sans rapport et mesurer le temps de bout en bout. Si les opérations centrales restent constantes mais que le temps augmente, chercher le travail encore absent des comptes le long du chemin de requête.
Après correction, un résumé n’est construit que s’il sert : 10 résumés, 50 contributeurs. Le système ne prépare plus les panneaux de toute la ville pour une promenade locale.
Matériaux : tests locaux de capacité de Discovery Front et analyse appariée du 1er septembre 2026. Cette révision a vérifié les comparaisons originales, la configuration et le code actuel de construction. Les extraits sont simplifiés pour l’explication. Voir SOURCE-NOTES.md pour les emplacements précis. Ce carnet réécrit une expérience existante.