Intermédiaire·3 min·3 juin 2026

Pourquoi chaque octet compte en performance

🎧 Résumé audio0:00 / 0:00
Doubler la taille d'une structure peut te coûter 4x plus lent en accès mémoire aléatoire.
Pourquoi chaque octet compte en performance

Pourquoi ça compte pour toi

Si tu construis un système qui traite beaucoup de données (jeux, data science, simulations), l'arrangement de tes structures en mémoire fait la différence entre 3 nanosecondes et 163 nanosecondes par accès. C'est pas de la micro-optimisation de barbu : c'est de l'architecture qui impacte directement ta capacité à monter en charge et tes coûts cloud.

Ce qu'il faut retenir

  • 1.Les processeurs chargent 64 octets à la fois : si tu n'utilises qu'1 octet, tu gaspilles 63 octets de cache
  • 2.Passer d'une structure de 64 o à 128 o te bascule du cache L1 (3 ns) au cache L2 (11 ns) à seulement 512 éléments
  • 3.L'arrangement en mémoire : Array of Structs (AoS) vs Struct of Arrays (SoA) peut donner 30x d'écart selon ton schéma d'accès

Tu galères avec le jargon ?

Lis la version réécrite en mode débutant — toutes les idées, sans le jargon.

Le hardware parle plus fort que l'algorithme

Depuis des années, on te dit que O(N) c'est O(N) : si ta boucle est linéaire, c'est linéaire. Faux.

Deux boucles apparemment identiques peuvent avoir des latences complètement différentes selon comment les données sont arrangées en mémoire et comment le CPU les charge.

Comment ça marche : les lignes de cache

Quand tu lis un octet, le CPU ne charge pas juste cet octet — il attrape 64 octets (ta ligne de cache) et les cale en cache L1. C'est une optimisation : les données qu'on accède sont généralement proches les unes des autres en mémoire.

Voilà les hiérarchies réelles :

  • Cache L1d : ~35 Kio/cœur, ~4-5 cycles, ~1-2 ns (35 Kio ÷ 64 o = ~560 lignes de cache)
  • Cache L2 : ~2 Mio/paire, ~12-15 cycles, ~4-5 ns
  • Cache L3 : 12 Mio partagé, ~30-40 cycles, ~10-15 ns
  • DRAM : mémoire principale, ~100-200 cycles, ~60-100 ns

Quand ta structure ne rentre plus en L1, tu tombes 4 à 10 fois plus lent. C'est violent.

Le cas concret : Array of Structs vs Struct of Arrays

Imagine une liste de 4096 monstres de jeu, chacun avec des stats (id, position xyz, vitesse xyz, hp, attaque, défense, vivant, équipe, nom).

Disposition classique (AoS) :

struct Monster {
  uint32_t id;        // 4 octets
  float x, y, z;      // 12 octets
  // ... autres champs
  uint8_t is_alive;   // 1 octet ← c'est le seul qu'on veut
};
// Total : 64 octets

Quand tu itères pour filtrer les vivants, tu charges 64 octets entiers par monstre. La ligne de cache contient UNE SEULE structure.

Disposition optimisée (SoA) :

struct Monsters {
  uint32_t *ids;
  float *xs, *ys, *zs;
  uint8_t *is_alives;  // 4096 octets de suite
};

Là, une seule ligne de cache (64 octets) contient 64 statuts de monstres différents. Tu en charges 64 d'un coup.

Résultat ? Jusqu'à 30x plus rapide avec la bonne structure pour le bon schéma d'accès.

Accès aléatoire : quand la taille totale devient le goulot

C'est pire avec les graphes, tables de hachage, ou le pointer-chasing (vraiment aléatoire). Le CPU ne peut pas prédire où tu vas aller — il faut que tout soit en cache pour ne pas caler.

Regarde les latences réelles mesurées :

Nombre de monstresEmpreinte 64 oLatence 64 oEmpreinte 128 oLatence 128 o
51232 Kio~3 ns64 Kio~11 ns
4 096256 Kio~11 ns512 Kio~13 ns
32 7682 Mio~29 ns4 Mio~43 ns
131 0728 Mio~163 ns16 Mio~162 ns

Doubler de 64 o à 128 o, c'est doubler ton empreinte mémoire. À 512 éléments, tu passes du L1 (3 ns) au L2 (11 ns). À 32k, c'est +50% de latence.

Donc ?

Aujourd'hui, beaucoup de devs ignorent où vivent leurs données. En Java tu ajoutes un champ, tu t'en fous. Mais sur du traitement en masse (ML, gaming, data processing), c'est ton deuxième goulot après l'algorithme.

Avant d'ajouter un truc à ta structure :

  • Demande-toi si c'est vraiment nécessaire
  • Mesure ton empreinte totale avec lscpu
  • Si tu fais de l'accès aléatoire, compte les mégaoctets
  • Envisage SoA pour le chemin critique

Chaque octet compte.

Et concrètement pour toi ?

Choisis ton profil — la lecture de l'article change selon qui tu es.

🔭 Curieux

Pour toi, retiens que chaque octet compte parce que les processeurs n'aiment pas attendre : la mémoire est le vrai goulot, pas la CPU. C'est pourquoi même l'IA et le cloud peuvent être bloqués par des choix de conception qu'on ne voit pas.

Newsletters Noésis

3 minutes d'IA dans ta boîte mail, chaque matin.

Rejoins les francophones qui comprennent, essaient et progressent avec l'IA. Choisis ce que tu veux recevoir. Désabonnement en 1 clic.