Benchmarks
Clause comparado con Erlang/OTP en una misma máquina: los mismos programas Erlang, compilados con erlc y con clau -O2, miden el tiempo de sus kernels tras una llamada de calentamiento. Estas cifras cambian con cada optimización.
- Media geométrica de los tiempos de los kernels, Clause -O2 frente al JIT de BEAM (OTP)
- 1,49× más rápido de media
- Kernels en los que Clause es más rápido
- 31 / 31
- Media geométrica el 2026-10-12, la primera ejecución registrada
- 20,2×
Tiempos de los kernels
Mediana de 3 ejecuciones en milisegundos. La barra muestra el tiempo de Clause dividido por el de OTP en escala logarítmica.
| Kernel | OTP JIT | Clause -O2 | Clause ÷ OTP | |
|---|---|---|---|---|
| Generación de datos | ||||
| bigint_factorialCalcula el factorial de 3000 con enteros grandes, 330 veces | 1620,17 | 212,76 | 0,13× | |
| binary_appendAñade 10 000 enteros de 32 bits a un binary creciente, 23 000 veces | 1080,93 | 802,57 | 0,74× | |
| list_of_tuplesConstruye una lista de 200 000 tuplas pequeñas, 260 veces | 1467,60 | 1128,44 | 0,77× | |
| list_to_tupleConvierte listas de 1000 elementos en tuplas, 170 000 veces | 1586,38 | 1278,69 | 0,81× | |
| map_putInserta 2000 claves enteras en un map, una a una, 4900 veces | 1605,84 | 1519,51 | 0,95× | |
| string_buildConstruye 20 000 cadenas a partir de enteros y átomos, 1000 veces | 1044,38 | 720,73 | 0,69× | |
| Procesamiento de datos | ||||
| binary_matchSuma 20 000 enteros de 32 bits extraídos de un binary, 49 000 veces | 1272,63 | 1071,47 | 0,84× | |
| comprehensionComprehension que filtra y duplica 20 000 enteros, 15 000 veces | 1407,08 | 893,85 | 0,64× | |
| int_to_listConvierte 20 000 enteros en cadenas y de vuelta, 2000 veces | 908,70 | 412,79 | 0,45× | |
| map_foldlAplica map y luego fold a 20 000 enteros, 4500 veces | 1500,77 | 1113,04 | 0,74× | |
| map_updateIncrementa cada valor de un map de 500 claves, 24 000 veces | 1151,28 | 669,97 | 0,58× | |
| small_mapActualiza 80 millones de veces un map de estado pequeño | 1486,44 | 1061,83 | 0,71× | |
| sortOrdena una lista de 20 000 enteros aleatorios, 600 veces | 1112,37 | 466,55 | 0,42× | |
| term_to_binaryCodifica y decodifica un término anidado grande, 4300 veces | 1433,29 | 1071,95 | 0,75× | |
| E/S de archivos | ||||
| large_readLee un archivo de 16 MB en bloques de 64 KB, 370 veces | 1444,15 | 1007,93 | 0,70× | |
| large_writeEscribe un archivo de 16 MB en bloques de 64 KB, 200 veces | 1019,80 | 989,09 | 0,97× | |
| read_fileLee un archivo entero de 16 MB en una sola llamada, 330 veces | 1485,52 | 1483,03 | 1,00× | |
| read_lineLee línea a línea un archivo de texto de 20 000 líneas, 52 veces | 1522,07 | 1467,28 | 0,96× | |
| small_filesEscribe, relee y borra 500 archivos pequeños, 11 veces | 1209,75 | 1116,40 | 0,92× | |
| Recolección de basura | ||||
| explicit_collectFuerza la recolección de basura con 10 000 tuplas vivas, 5100 veces | 1547,98 | 639,85 | 0,41× | |
| grow_shrinkHace crecer el heap con una lista de 200 000 elementos y la suelta, 300 veces | 1041,41 | 861,75 | 0,83× | |
| long_lived_churnMantiene una ventana deslizante de 10 000 elementos vivos entre basura, 370 veces | 1351,27 | 1095,82 | 0,81× | |
| short_processesLanza 5000 procesos efímeros que generan basura cada uno, 69 veces | 1667,28 | 1037,98 | 0,62× | |
| Bibliotecas | ||||
| qlcEjecuta la transformación de qlc sobre 27 consultas y 3 módulos, 11 veces | 1873,72 | 1714,66 | 0,92× | |
| Paso de mensajes | ||||
| fan_in100 procesos envían 1000 mensajes cada uno a uno solo, 25 veces | 1402,68 | 391,78 | 0,28× | |
| large_messageEnvía una lista de 100 000 elementos a otro proceso y de vuelta, 560 veces | 1063,94 | 789,04 | 0,74× | |
| ping_pongRebota un mensaje entre dos procesos 2 millones de veces | 1504,97 | 904,20 | 0,60× | |
| ringPasa un testigo 3050 vueltas por un anillo de 1000 procesos | 1438,21 | 1099,66 | 0,76× | |
| Sockets de loopback | ||||
| tcp_connectAbre 900 conexiones TCP en loopback con eco de 25 mensajes de 1 KB en cada una | 1418,85 | 1047,85 | 0,74× | |
| tcp_echoHace eco de 30 000 mensajes de 1 KB por TCP en loopback | 1455,62 | 1136,06 | 0,78× | |
| udp_round_tripRebota un datagrama de 1 KB 27 900 veces por UDP en loopback | 1458,07 | 1196,82 | 0,82× | |
Programas completos
Tiempo real en segundos, incluido el arranque, mediana de las ejecuciones.
| Programa | OTP JIT | Clause -O2 | Clause ÷ OTP | |
|---|---|---|---|---|
| bench_datagenConstruye en masa listas, tuplas, maps, binaries y enteros grandes | 8,54 | 5,72 | 0,67× | |
| bench_dataprocOrdenación, fold, actualización de maps, matching de binaries y conversiones | 10,45 | 6,76 | 0,65× | |
| bench_fileEscritura y lectura de archivos pequeños y grandes, lectura por líneas | 6,95 | 6,24 | 0,90× | |
| bench_gcProcesos efímeros, heap que crece y encoge, datos vivos | 5,83 | 3,69 | 0,63× | |
| bench_libraryLa parse transform de qlc en tiempo de ejecución, como la usa qlc:q/1 | 2,30 | 1,89 | 0,82× | |
| bench_msgPing-pong, fan-in, anillo de procesos y copia de mensajes grandes | 5,69 | 3,28 | 0,58× | |
| bench_socketEco TCP, conexiones TCP e idas y vueltas UDP en loopback | 5,99 | 4,57 | 0,76× |
Progreso
Media geométrica del tiempo de Clause dividido por el de OTP en cada día con ejecuciones registradas. Las ejecuciones anteriores al 2026-10-21 no estaban fijadas a un conjunto de CPU, por lo que parte del cambio de ese día se debe a la fijación.
| Fecha | 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× |
Tamaño de los ejecutables
Tamaño en megabytes de los programas de prueba tal como Clause los compila en cada nivel de optimización.
| Programa | -O0 | -O2 | -O2 --lto |
|---|---|---|---|
| bench_datagen | 9,90 MB | 9,82 MB | 9,82 MB |
| bench_dataproc | 10,42 MB | 10,01 MB | 10,01 MB |
| bench_file | 11,34 MB | 10,59 MB | 10,59 MB |
| bench_gc | 9,89 MB | 9,81 MB | 9,81 MB |
| bench_library | 10,24 MB | 9,94 MB | 9,95 MB |
| bench_msg | 9,91 MB | 9,82 MB | 9,82 MB |
| bench_socket | 11,58 MB | 10,64 MB | 10,65 MB |
Tamaños con -O2 de las últimas 6 ejecuciones de benchmarks, de la más antigua a la más reciente, un commit de Clause por ejecución. La tabla siguiente añade el total de todos los programas bench_* y el tamaño del compilador clau.
- 2026-10-207d7a2f2e
- 2026-10-2171ec52f8
- 2026-10-23dea68508
- 2026-10-24af105043
- 2026-10-26d6eafa72
- 2026-10-30f4e5f3e0
| Fecha | Commit | Todos los programas bench_* | clau |
|---|---|---|---|
| 2026-10-20 | 7d7a2f2e | 38,59 MB | 59,50 MB |
| 2026-10-21 | 71ec52f8 | 38,78 MB | 59,54 MB |
| 2026-10-23 | dea68508 | 38,79 MB | 59,54 MB |
| 2026-10-24 | af105043 | 38,81 MB | 59,65 MB |
| 2026-10-26 | d6eafa72 | 62,21 MB | 59,98 MB |
| 2026-10-30 | f4e5f3e0 | 70,63 MB | 60,75 MB |
Configuración
- Máquina
- Intel64 Family 6 Model 183 Stepping 1, GenuineIntel, 32 CPU lógicas, Windows 11 (10.0.26200)
- Conjunto de CPU
- Núcleos de rendimiento 0-15, 16 de 32 CPU lógicas
- Erlang/OTP
- 29, ERTS 17.1
- Commit de Clause
- f4e5f3e0
- Ejecución
- 2026-10-30
OTP y Clause se ejecutan en las mismas CPU: cada programa de benchmark está fijado a los núcleos de rendimiento del procesador, de modo que en una CPU híbrida ningún kernel acaba en un núcleo de eficiencia más lento. Ambos mantienen un planificador activo por cada CPU del conjunto, sin vincularlo a ninguna CPU concreta dentro de él.
Para ejecutar los benchmarks, use make benchmark o make-benchmark.bat en el repositorio de Clause; las notas de benchmarks describen los programas y las opciones. Notas de benchmarks
Clause