Benchmarks
Clause comparé à Erlang/OTP sur une même machine : les mêmes programmes Erlang, compilés par erlc et par clau -O2, chronomètrent leurs noyaux après un appel de préchauffage. Ces chiffres évoluent à chaque optimisation.
- Moyenne géométrique des temps des noyaux, Clause -O2 face au JIT de BEAM (OTP)
- 1,49× plus rapide en moyenne
- Noyaux où Clause est plus rapide
- 31 / 31
- Moyenne géométrique au 2026-10-12, première exécution enregistrée
- 20,2×
Temps des noyaux
Médiane de 3 exécutions en millisecondes. La barre montre le temps de Clause divisé par celui d'OTP sur une échelle logarithmique.
| Noyau | OTP JIT | Clause -O2 | Clause ÷ OTP | |
|---|---|---|---|---|
| Génération de données | ||||
| bigint_factorialCalcule la factorielle de 3000 en grands entiers, 330 fois | 1 620,17 | 212,76 | 0,13× | |
| binary_appendAjoute 10 000 entiers 32 bits à un binary croissant, 23 000 fois | 1 080,93 | 802,57 | 0,74× | |
| list_of_tuplesConstruit une liste de 200 000 petits tuples, 260 fois | 1 467,60 | 1 128,44 | 0,77× | |
| list_to_tupleConvertit des listes de 1000 éléments en tuples, 170 000 fois | 1 586,38 | 1 278,69 | 0,81× | |
| map_putInsère 2000 clés entières dans une map, une à une, 4900 fois | 1 605,84 | 1 519,51 | 0,95× | |
| string_buildConstruit 20 000 chaînes à partir d'entiers et d'atomes, 1000 fois | 1 044,38 | 720,73 | 0,69× | |
| Traitement de données | ||||
| binary_matchAdditionne 20 000 entiers 32 bits extraits d'un binary, 49 000 fois | 1 272,63 | 1 071,47 | 0,84× | |
| comprehensionComprehension qui filtre et double 20 000 entiers, 15 000 fois | 1 407,08 | 893,85 | 0,64× | |
| int_to_listConvertit 20 000 entiers en chaînes et inversement, 2000 fois | 908,70 | 412,79 | 0,45× | |
| map_foldlApplique map puis fold à 20 000 entiers, 4500 fois | 1 500,77 | 1 113,04 | 0,74× | |
| map_updateIncrémente chaque valeur d'une map de 500 clés, 24 000 fois | 1 151,28 | 669,97 | 0,58× | |
| small_mapMet à jour 80 millions de fois une petite map d'état | 1 486,44 | 1 061,83 | 0,71× | |
| sortTrie une liste de 20 000 entiers aléatoires, 600 fois | 1 112,37 | 466,55 | 0,42× | |
| term_to_binaryEncode et décode un grand terme imbriqué, 4300 fois | 1 433,29 | 1 071,95 | 0,75× | |
| E/S fichiers | ||||
| large_readLit un fichier de 16 Mo par blocs de 64 Ko, 370 fois | 1 444,15 | 1 007,93 | 0,70× | |
| large_writeÉcrit un fichier de 16 Mo par blocs de 64 Ko, 200 fois | 1 019,80 | 989,09 | 0,97× | |
| read_fileLit un fichier entier de 16 Mo en un seul appel, 330 fois | 1 485,52 | 1 483,03 | 1,00× | |
| read_lineLit ligne par ligne un fichier texte de 20 000 lignes, 52 fois | 1 522,07 | 1 467,28 | 0,96× | |
| small_filesÉcrit, relit et supprime 500 petits fichiers, 11 fois | 1 209,75 | 1 116,40 | 0,92× | |
| Ramasse-miettes | ||||
| explicit_collectForce le ramasse-miettes avec 10 000 tuples vivants, 5100 fois | 1 547,98 | 639,85 | 0,41× | |
| grow_shrinkFait grossir le tas avec une liste de 200 000 éléments, puis la libère, 300 fois | 1 041,41 | 861,75 | 0,83× | |
| long_lived_churnGarde une fenêtre glissante de 10 000 éléments vivants parmi les déchets, 370 fois | 1 351,27 | 1 095,82 | 0,81× | |
| short_processesLance 5000 processus éphémères qui produisent chacun des déchets, 69 fois | 1 667,28 | 1 037,98 | 0,62× | |
| Bibliothèques | ||||
| qlcExécute la transformation qlc sur 27 requêtes et 3 modules, 11 fois | 1 873,72 | 1 714,66 | 0,92× | |
| Passage de messages | ||||
| fan_in100 processus envoient chacun 1000 messages à un seul, 25 fois | 1 402,68 | 391,78 | 0,28× | |
| large_messageEnvoie une liste de 100 000 éléments à un autre processus, aller-retour, 560 fois | 1 063,94 | 789,04 | 0,74× | |
| ping_pongRenvoie un message entre deux processus 2 millions de fois | 1 504,97 | 904,20 | 0,60× | |
| ringFait passer un jeton 3050 fois dans un anneau de 1000 processus | 1 438,21 | 1 099,66 | 0,76× | |
| Sockets en boucle locale | ||||
| tcp_connectOuvre 900 connexions TCP sur loopback, avec 25 échos de 1 Ko sur chacune | 1 418,85 | 1 047,85 | 0,74× | |
| tcp_echoRenvoie en écho 30 000 messages de 1 Ko en TCP sur loopback | 1 455,62 | 1 136,06 | 0,78× | |
| udp_round_tripRenvoie un datagramme de 1 Ko 27 900 fois en UDP sur loopback | 1 458,07 | 1 196,82 | 0,82× | |
Programmes complets
Temps réel en secondes, démarrage compris, médiane des exécutions.
| Programme | OTP JIT | Clause -O2 | Clause ÷ OTP | |
|---|---|---|---|---|
| bench_datagenConstruit en masse listes, tuples, maps, binaries et grands entiers | 8,54 | 5,72 | 0,67× | |
| bench_dataprocTri, fold, mises à jour de maps, filtrage de binaries, conversions | 10,45 | 6,76 | 0,65× | |
| bench_fileÉcriture et lecture de petits et grands fichiers, lecture par ligne | 6,95 | 6,24 | 0,90× | |
| bench_gcProcessus éphémères, tas qui grossit puis rétrécit, données vivantes | 5,83 | 3,69 | 0,63× | |
| bench_libraryLa parse transform de qlc à l'exécution, telle que qlc:q/1 l'utilise | 2,30 | 1,89 | 0,82× | |
| bench_msgPing-pong, fan-in, anneau de processus et copie de gros messages | 5,69 | 3,28 | 0,58× | |
| bench_socketÉcho TCP, connexions TCP et allers-retours UDP sur loopback | 5,99 | 4,57 | 0,76× |
Progression
Moyenne géométrique du temps de Clause divisé par celui d'OTP pour chaque jour d'exécution enregistré. Les exécutions antérieures au 2026-10-21 n'étaient pas épinglées à un ensemble de processeurs ; une partie de l'évolution de ce jour-là vient donc de l'épinglage.
| Date | Commit | Clause ÷ OTP |
|---|---|---|
| 2026-10-12 | a7bc0c9b | 20,2× |
| 2026-10-13 | 8a244d9c | 16,9× |
| 2026-10-14 | 55f42a9d | 16,9× |
| 2026-10-15 | 6ed3851c | 2,73× |
| 2026-10-16 | 97295c84 | 1,95× |
| 2026-10-17 | a8c3f8f6 | 1,38× |
| 2026-10-18 | 336caea7 | 1,41× |
| 2026-10-20 | 7d7a2f2e | 1,00× |
| 2026-10-21 | 71ec52f8 | 0,78× |
| 2026-10-23 | dea68508 | 0,69× |
| 2026-10-24 | af105043 | 0,65× |
| 2026-10-26 | d6eafa72 | 0,71× |
| 2026-10-30 | f4e5f3e0 | 0,67× |
Taille des exécutables
Taille en mégaoctets des programmes de test tels que Clause les construit à chaque niveau d'optimisation.
| Programme | -O0 | -O2 | -O2 --lto |
|---|---|---|---|
| bench_datagen | 9,90 Mo | 9,82 Mo | 9,82 Mo |
| bench_dataproc | 10,42 Mo | 10,01 Mo | 10,01 Mo |
| bench_file | 11,34 Mo | 10,59 Mo | 10,59 Mo |
| bench_gc | 9,89 Mo | 9,81 Mo | 9,81 Mo |
| bench_library | 10,24 Mo | 9,94 Mo | 9,95 Mo |
| bench_msg | 9,91 Mo | 9,82 Mo | 9,82 Mo |
| bench_socket | 11,58 Mo | 10,64 Mo | 10,65 Mo |
Tailles en -O2 des 6 dernières exécutions des benchmarks, de la plus ancienne à la plus récente, un commit de Clause par exécution. Le tableau ci-dessous ajoute le total de tous les programmes bench_* et la taille du compilateur clau.
- 2026-10-207d7a2f2e
- 2026-10-2171ec52f8
- 2026-10-23dea68508
- 2026-10-24af105043
- 2026-10-26d6eafa72
- 2026-10-30f4e5f3e0
| Date | Commit | Tous les programmes bench_* | clau |
|---|---|---|---|
| 2026-10-20 | 7d7a2f2e | 38,59 Mo | 59,50 Mo |
| 2026-10-21 | 71ec52f8 | 38,78 Mo | 59,54 Mo |
| 2026-10-23 | dea68508 | 38,79 Mo | 59,54 Mo |
| 2026-10-24 | af105043 | 38,81 Mo | 59,65 Mo |
| 2026-10-26 | d6eafa72 | 62,21 Mo | 59,98 Mo |
| 2026-10-30 | f4e5f3e0 | 70,63 Mo | 60,75 Mo |
Configuration
- Machine
- Intel64 Family 6 Model 183 Stepping 1, GenuineIntel, 32 processeurs logiques, Windows 11 (10.0.26200)
- Ensemble de processeurs
- Cœurs de performance 0-15, 16 sur 32 processeurs logiques
- Erlang/OTP
- 29, ERTS 17.1
- Commit Clause
- f4e5f3e0
- Exécution
- 2026-10-30
OTP et Clause s'exécutent sur les mêmes processeurs : chaque programme de benchmark est épinglé aux cœurs de performance du processeur, si bien que sur un processeur hybride aucun noyau (kernel) ne tombe sur un cœur d'efficacité plus lent. Les deux gardent un ordonnanceur actif par processeur de cet ensemble, sans le lier à un processeur précis de l'ensemble.
Pour lancer les benchmarks vous-même, utilisez make benchmark ou make-benchmark.bat dans le dépôt Clause ; les notes de benchmark décrivent les programmes et les options. Notes de benchmark
Clause