Aller au contenu principal

Niveaux d’abstraction : du code source à la machine

« Haut niveau » et « bas niveau » décrivent la distance entre ce que le code exprime et les détails de la machine qu’il faut gérer. Ce ne sont ni des notes de qualité, ni un classement automatique des performances.

Le même besoin, plusieurs niveaux

Prenons un besoin observable : augmenter le code du caractère a, puis afficher b.

En Python, les opérations sur les nombres, les chaînes et la sortie standard sont fournies par l’environnement :

code = ord("a")
print(chr(code + 1))

En C, le programme nomme le type de la valeur et appelle une fonction de la bibliothèque standard :

#include <stdio.h>

int main(void) {
char letter = 'a';
putchar(letter + 1);
return 0;
}

En assembleur, les instructions et conventions dépendent de l’architecture et du système. Cet extrait x86-64 pour Linux place les arguments d’un appel système dans des registres précis :

section .data
letter db 'b'

section .text
global _start
_start:
mov rax, 1 ; write
mov rdi, 1 ; stdout
mov rsi, letter ; adresse des octets
mov rdx, 1 ; longueur
syscall

Les trois extraits expriment un résultat proche, mais ne délèguent pas les mêmes décisions à l’outil ou au runtime.

Ce qu’un niveau plus élevé abstrait

Selon le langage et son implémentation, le programmeur peut déléguer :

  • la représentation et l’allocation des valeurs ;
  • la gestion de la mémoire ;
  • les conventions d’appel ;
  • le choix exact des instructions processeur ;
  • une partie de la portabilité entre systèmes et architectures.

Cette délégation rend certaines intentions plus courtes à exprimer. Elle ne dit pas à elle seule comment le programme sera exécuté ni combien de ressources il consommera.

Langage, implémentation et chaîne d’outils

Un fichier source ne devient pas directement une action du processeur. Il passe par une chaîne concrète : analyse, transformations intermédiaires, bibliothèques, runtime, système d’exploitation et enfin instructions machine.

Par exemple, un moteur JavaScript peut analyser le source, produire une représentation intermédiaire, interpréter certaines parties et compiler à la volée les portions souvent exécutées. Un programme C est généralement compilé en fichiers objets, lié avec des bibliothèques, puis chargé par le système. Les mots « compilé » et « interprété » décrivent donc des étapes d’implémentation, pas une propriété exclusive et immuable du langage.

Performance : mesurer la chaîne réelle

Un niveau d’abstraction ne permet pas de conclure qu’un programme sera « rapide » ou « lent ». Le coût observé dépend notamment de l’algorithme, de l’implémentation du langage, des optimisations, des entrées, des accès mémoire, des entrées-sorties et du matériel. Une comparaison utile fixe une charge de travail et mesure le même résultat dans un environnement documenté.

Vérification observable

Pour une application web que tu utilises, écris une chaîne sous cette forme :

fichier source → outil ou moteur → représentation intermédiaire éventuelle
→ runtime / système → processeur

La vérification est réussie si tu peux :

  1. nommer au moins un fichier source réel ;
  2. nommer l’outil ou l’environnement qui le traite ;
  3. distinguer une transformation d’une exécution ;
  4. expliquer pourquoi cette chaîne ne permet pas, seule, de prédire la performance.