Números com as condições à vista.
Builds Release em um Intel i7-6700 (Skylake, AVX2, 4 núcleos): Windows x64 com MSVC 19.51 e Linux x64 no WSL2 com GCC 15.2. Algumas medições de referência mais antigas foram feitas com MSVC 19.44 e GCC 13.3, e o README de cada módulo informa o compilador. Os números são medianas ou o melhor de várias execuções, conforme cada README. Quando há dois valores, o do Windows vem primeiro. Quando há só um, a linha diz qual é a plataforma.
Vazão
Latência
| Operação | Módulo | Medido |
|---|---|---|
| Emitir um sinal sem ouvintes | event | 0,54 ns |
| Tick do scheduler ocioso, com o relógio já lido | scheduler | 1,97 / 0,71 ns |
| Buscar uma mensagem traduzida | i18n | 1,4 a 2,6 ns |
| Propriedades Unicode de um code point | text | 2,2 / 2,6 ns |
| Leitura de config por handle | config | 3,52 ns |
| Incrementar um contador de telemetria | telemetria | 4,88 a 4,98 ns |
| Troca de fiber bruta, Windows | coroutine | 16 a 18 ns |
| Ler o relógio monotônico | time | 18,75 / 22,00 ns |
| Armar um timer com um milhão já ativos | time | 20 a 23 ns |
| Chamada RPC unária, transporte nulo, Windows | rpc | 617 a 714 ns |
| Abrir um banco chave-valor de 1 GB após um fechamento limpo | storage | 1,49 / 0,92 ms |
Comparação com as referências
Regex vs std::regex. De 10× a 351× mais rápido que a libstdc++ em seis de sete padrões (8× no sétimo) e de 1,3× a 42× mais rápido que a do MSVC, com tempo linear. O std::regex roda sobre 512 KB do mesmo texto de 2 MB, com o resultado ajustado na proporção.
Formatação de inteiros vs snprintf. 5,4× mais rápido. À parte, o writer de terminal transforma 100.000 escritas de um byte em /dev/null em 25 chamadas a write.
Busca vetorial vs hnswlib 0.8. SIFT1M, uma thread, Linux: recall@10 de 0,9633 contra 0,9634, com vazão comparável (4.485 a 5.663 contra 4.624 consultas/s). Índice construído em 478 s, contra 525 s.
Matemática AVX2 vs escalar. Normalização em lote no layout structure-of-arrays, 512 pontos no L1: 8,1× / 9,0× sobre o caminho escalar, que é compilado sem autovetorização. Todos os caminhos devolvem os mesmos bits, sem contração FMA.
Conferido com código que não escrevemos.
| Área | Conferido com | Resultado |
|---|---|---|
| Ed25519 | OpenSSL, uma referência em Python com inteiros exatos e os vetores da RFC 8032 | 11.848 · 0 divergências |
| SHA-384/512, HMAC, HKDF, AES-GCM | Python cryptography 46 e hashlib sobre OpenSSL 3.5, além de 47 vetores oficiais | 127.502 · 0 divergências |
| X25519, P-256, P-384, verificação RSA | os mesmos oráculos, mais as RFC 7748 e 6979 | 59.001 · 0 divergências |
| X.509 | openssl verify e Python cryptography, com cadeias aleatórias | 23,643 |
| TLS 1.3 | trace da RFC 8448, openssl s_server e s_client, ssl do Python | 31 casos · 0 falhas |
| Compressão | liblz4, zlib e libxxhash, no Linux | 79.864 · 0 divergências |
| Unicode 18 | os arquivos oficiais de conformidade do Unicode | 100% |
| Machine learning | scikit-learn, LightGBM, XGBoost, ONNX Runtime, hnswlib, scipy | até 1e-4 de diferença, ou idêntico bit a bit, e o recall do hnswlib |
| Telemetria | Prometheus e OpenTelemetry Collector reais | aceito sem nenhuma rejeição |
| Build | Testes |
|---|---|
| Windows x64, MSVC 19.51, Release | 282 de 282 |
| Linux x64, GCC 15.2, Release | 284 de 284 |
| Linux x64, com Guard e ML ligados | 287 de 287 |
| Linux x64, ASan e UBSan | 274 · limpo, 17 out. |
| Linux x64, TSan | 274 de 274 · limpo, 17 out. |
Scripts de mutação inserem o bug e exigem que o teste quebre. Foi assim que pegamos uma chave de ofuscação que se anulava sozinha e um caso de falsificação Ed25519, enquanto todos os testes de ida e volta passavam.
Um projeto separado é compilado contra o SDK empacotado com find_package, do jeito que um cliente usa. Cada header público compila sozinho, no MSVC e no GCC.
MSVC /W4 e GCC -Wall -Wextra, incluindo as árvores de build com sanitizers.
Onde roda, sem rodeios.
24 metas que não batemos. Ainda.
Cada módulo tem a própria especificação, com metas de desempenho. Estas são as que as medições dele não alcançaram, conforme registrado na documentação do módulo. Preferimos que você as leia aqui a descobri-las em produção.
| Módulo | Medido vs. meta |
|---|---|
| coroutine | Fiber vs. thread: de 16x a 28x mais barata. Meta de 50x não cumprida |
| coroutine | Criação de uma tarefa: 80 a 250 ns. Meta de 100 ns não cumprida de forma consistente |
| resilience | Cadeia de quatro políticas: 101 a 123 ns. Meta de 50 ns não cumprida |
| cache | Leitura com acerto: 20,7 ns. Meta de 20 ns não cumprida |
| cache | Vazão de leitura de 1 a 8 threads: 2x. Meta de 10x de 1 a 16 threads não cumprida (4 núcleos físicos) |
| compression | Bloco LZ4, texto: comprime a 365 e 380 MB/s, contra 391,2 MB/s da referência LZ4_compress_default na mesma máquina. Meta de 600 MB/s não cumprida. Descomprime a 3,24 GB/s no Windows e 2,48 GB/s no Linux (a meta de 3 GB/s só é cumprida no Windows) |
| compression | CRC32 (polinômio IEEE), tabela slice-by-8: 1,57 GB/s no Windows e 2,38 GB/s no Linux. Meta de 20 GB/s não cumprida: a instrução x86 CRC32 só calcula o CRC32C, que chega lá |
| encoding | Validação UTF-8, texto misto: 6,7 GB/s com AVX2. Meta de 15 GB/s não cumprida |
| config | Vazão do parser, arquivo de 0,59 MB (MSVC 19.51, i7-6700): 133 MB/s. Meta de 200 MB/s não cumprida |
| storage | Leitura pontual aleatória num banco de 115 MB, maior que o cache da CPU: 831 a 1.578 ns e 870 a 1.176 ns. Meta de 1 µs não cumprida de forma consistente |
| regex | Contra std::regex, 7 padrões sobre 2 MB: de 10x a 351x vs. libstdc++ em seis dos sete, de 1,3x a 42x vs. MSVC. Meta de 10x em todos não cumprida |
| regex | Compilação de um padrão: 1,0x a 2,2x a velocidade do std::regex no GCC, 0,2x a 0,7x no MSVC. Meta de ser 10x mais rápido não cumprida |
| rpc | Alocações por chamada: 1. Meta de zero não cumprida |
| bench | Repetibilidade em 10 execuções: 0,4% a 14,1% e 1,3% a 14,1%. Meta de 2% não cumprida nesta máquina |
| math | Produto escalar e vetorial em pontos intercalados: 2,7x e 1,9x a 2,2x, distância intercalada 2,8x no MSVC. Meta de 3x a 4x não cumprida (as variantes structure-of-arrays chegam de 4,1x a 4,8x) |
| ecs | Iterar 1 milhão com 3 componentes: 4,19 ms, no limite da banda de memória (14,3 GB/s). Meta de 1 ms não cumprida |
| Ml::Trees | Uma predição com 500 árvores: 12 a 14 µs com AVX2. Meta de 50 ns não cumprida (o piso da memória é de 4 a 5 µs) |
| Ml::Trees | Verificação completa de um modelo de 100 MB: cerca de 13 ms. Meta de 5 ms não cumprida |
| Ml::Trees | Predição em lote: 1,5x a 1,65x mais rápida por linha do que uma de cada vez. Meta de 4x não cumprida |
| Ml::Trees | Modo compilado: 2,7x mais lento que o interpretador AVX2. Meta de ser 2x mais rápido não cumprida |
| Ml::Features | Um evento com 50 features: 0,45 µs com uma entidade, 1,8 µs com 10.000. Meta de 100 ns não cumprida |
| Ml::Anomaly | Autoencoder: a feature que mais contribui é a responsável em 94,3% dos casos. A meta de 95% definida para os outros detectores não é cumprida |
| ModelGuard | Verificar e descriptografar 50 MB: cerca de 330 a 380 ms. Meta de 10 ms não cumprida |
| VectorIndex | Meta de 10.000 consultas/s com recall de 95% em 1M x 768 não cumprida |
Meça na sua própria máquina.
O harness de benchmark vem com a biblioteca. Meça a sua própria carga de trabalho durante os 30 dias de avaliação.