bun add mitata
npm install mitata
experimente o mitota no navegador com o assistente de IA em https://bolt.new/~/mitata
node --expose-gc ...
)javascript | cabeçalho único c++ |
---|---|
import { run , bench , boxplot } from 'mitata' ;
function fibonacci ( n ) {
if ( n <= 1 ) return n ;
return fibonacci ( n - 1 ) + fibonacci ( n - 2 ) ;
}
bench ( 'fibonacci(40)' , ( ) => fibonacci ( 40 ) ) ;
boxplot ( ( ) => {
bench ( 'Array.from($size)' , function * ( state ) {
const size = state . get ( 'size' ) ;
yield ( ) => Array . from ( { length : size } ) ;
} ) . range ( 'size' , 1 , 1024 ) ;
} ) ;
await run ( ) ; | # include " src/mitata.hpp "
int fibonacci ( int n) {
if (n <= 1 ) return n;
return fibonacci (n - 1 ) + fibonacci (n - 2 );
}
int main () {
mitata::runner runner;
runner. bench ( " noop " , []() { });
runner. summary ([&]() {
runner. bench ( " empty fn " , []() { });
runner. bench ( " fibonacci " , []() { fibonacci ( 20 ); });
});
auto stats = runner. run ();
} |
import { run } from 'mitata' ;
await run ( { format : 'mitata' , colors : false } ) ; // default format
await run ( { filter : / new Array.* / } ) // only run benchmarks that match regex filter
await run ( { throw : true } ) ; // will immediately throw instead of handling error quietly
// c++
auto stats = runner . run ( { . colors = true , . format = "json" , . filter = std :: regex ( ".*" ) } ) ;
Em tempos de execução que expõem gc (por exemplo, bun, node --expose-gc ...
), o mitata executará automaticamente a coleta de lixo antes de cada benchmark.
Este comportamento pode ser ainda mais personalizado através da função gc
em cada benchmark (você só deve fazer isso quando for absolutamente necessário - grandes picos de gc):
bench ( 'lots of allocations' , ( ) => {
Array . from ( { length : 1024 } , ( ) => Array . from ( { length : 1024 } , ( ) => new Array ( 1024 ) ) ) ;
} )
// false | 'once' (default) | 'inner'
// once runs gc after warmup
// inner runs gc after warmup and before each (batch-)iteration
. gc ( 'inner' ) ;
O mitata pronto para uso pode detectar o mecanismo/tempo de execução em que está sendo executado e voltar a usar funções alternativas de E/S não padrão. Se o seu mecanismo ou tempo de execução não tiver suporte, abra um problema ou solicite suporte.
$ xs bench.mjs
$ quickjs bench.mjs
$ d8 --expose-gc bench.mjs
$ spidermonkey -m bench.mjs
$ graaljs --js.timer-resolution=1 bench.mjs
$ /System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc bench.mjs
// bench.mjs
import { print } from './src/lib.mjs' ;
import { run , bench } from './src/main.mjs' ; // git clone
import { run , bench } from './node_modules/mitata/src/main.mjs' ; // npm install
print ( 'hello world' ) ; // works on every engine
Com outras bibliotecas de benchmarking, muitas vezes é muito difícil fazer benchmarks que vão além de um intervalo ou executar a mesma função com argumentos diferentes sem escrever código espaguete, mas agora com o mitata, converter seu benchmark para usar argumentos é apenas uma chamada de função de distância.
import { bench } from 'mitata' ;
bench ( function * look_mom_no_spaghetti ( state ) {
const len = state . get ( 'len' ) ;
const len2 = state . get ( 'len2' ) ;
yield ( ) => new Array ( len * len2 ) ;
} )
. args ( 'len' , [ 1 , 2 , 3 ] )
. range ( 'len' , 1 , 1024 ) // 1, 8, 64, 512...
. dense_range ( 'len' , 1 , 100 ) // 1, 2, 3 ... 99, 100
. args ( { len : [ 1 , 2 , 3 ] , len2 : [ '4' , '5' , '6' ] } ) // every possible combination
Para casos em que você precisa de uma cópia exclusiva do valor para cada iteração, o mitata suporta a criação de parâmetros computados que não contam para os resultados do benchmark (nota: não há garantia de tempo de recomputação, ordem ou contagem de chamadas) :
bench ( 'deleting $keys from object' , function * ( state ) {
const keys = state . get ( 'keys' ) ;
const obj = { } ;
for ( let i = 0 ; i < keys ; i ++ ) obj [ i ] = i ;
yield {
[ 0 ] ( ) {
return { ... obj } ;
} ,
bench ( p0 ) {
for ( let i = 0 ; i < keys ; i ++ ) delete p0 [ i ] ;
} ,
} ;
} ) . args ( 'keys' , [ 1 , 10 , 100 ] ) ;
bun add @mitata/counters
npm install @mitata/counters
compatível com: macos (apple silicon) | linux (amd64, aarch64)
Ao instalar o pacote @mitata/counters
você pode habilitar a coleta e exibição de contadores de hardware para benchmarks.
------------------------------------------- -------------------------------
new Array ( 1024 ) 332.67 ns/iter 337 . 90 ns █
( 295.63 ns … 507 . 93 ns ) 455 . 66 ns ▂██▇▄▂▂▂▁▂▁▃▃▃▂▂▁▁▁▁▁
2 . 41 ipc ( 48.66 % stalls ) 37 . 89 % L1 data cache
1.11 k cycles 2.69 k instructions 33.09 % retired LD / ST ( 888.96 )
new URL ( google . com ) 246 . 40 ns /iter 245 . 10 ns █▃
( 206.01 ns … 841 . 23 ns ) 302 . 39 ns ▁▁▁▁▂███▇▃▂▂▂▂▂▂▂▁▁▁▁
4 . 12 ipc ( 1.05 % stalls ) 98 . 88 % L1 data cache
856.49 cycles 3.53 k instructions 28.65 % retired LD / ST ( 1.01 k )
Para aqueles que adoram fazer micro-benchmarks, o mitata pode detectar e informar automaticamente sobre passagens de otimização, como eliminação de código morto, sem exigir nenhum sinalizador de mecanismo especial.
-------------------------------------- -------------------------------
1 + 1 318.63 ps/iter 325 . 37 ps ▇ █ !
( 267.92 ps … 14 . 28 ns ) 382 . 81 ps ▁▁▁▁▁▁▁█▁▁█▁▁▁▁▁▁▁▁▁▁
empty function 319 . 36 ps /iter 325 . 37 ps █ ▅ !
( 248.62 ps … 46 . 61 ns ) 382 . 81 ps ▁▁▁▁▁▁▃▁▁█▁█▇▁▁▁▁▁▁▁▁
! = benchmark was likely optimized out ( dead code elimination )
com os recursos de renderização ascii do mitata, agora você pode visualizar facilmente amostras em gráficos de barras, gráficos de caixa, gráficos de linhas, histogramas e obter resumos claros sem quaisquer ferramentas ou dependências adicionais.
-------------------------------------- -------------------------------
1 + 1 318.11 ps/iter 325 . 37 ps ▇ █ !
( 267.92 ps … 11 . 14 ns ) 363 . 97 ps ▁▁▁▁▁▁▁▁█▁▁▁█▁▁▁▁▁▁▁▁
Date . now ( ) 27.69 ns/iter 27 . 48 ns █
( 27.17 ns … 44 . 10 ns ) 32 . 74 ns ▃█▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
┌ ┐
1 + 1 ┤■ 318.11 ps
Date . now ( ) ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 27.69 ns
└ ┘
-------------------------------------- -------------------------------
Bubble Sort 2.11 ms/iter 2 . 26 ms █
( 1.78 ms … 6 . 93 ms ) 4 . 77 ms ▃█▃▆▅▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
Quick Sort 159 . 60 µs /iter 154 . 50 µs █
( 133.13 µs … 792 . 21 µs ) 573 . 00 µs ▅█▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
Native Sort 97 . 20 µs /iter 97 . 46 µs ██
( 90.88 µs … 688 . 92 µs ) 105 . 00 µs ▁▁▂▁▁▂▇██▇▃▃▃▃▃▂▂▂▁▁▁
┌ ┐
╷┌─┬─┐ ╷
Bubble Sort ├┤ │ ├───────────────────────┤
╵└─┴─┘ ╵
┬ ╷
Quick Sort │───┤
┴ ╵
┬
Native Sort │
┴
└ ┘
90 . 88 µs 2 . 43 ms 4 . 77 ms
-------------------------------------- -------------------------------
new Array ( 1 ) 3.57 ns/iter 3 . 20 ns 6 . 64 ns ▁█▄▂▁▁▁▁▁▁
new Array ( 8 ) 5 . 21 ns /iter 4 . 31 ns 8 . 85 ns ▁█▄▁▁▁▁▁▁▁
new Array ( 64 ) 17 . 94 ns /iter 13 . 40 ns 171 . 89 ns █▂▁▁▁▁▁▁▁▁
new Array ( 512 ) 188 . 05 ns /iter 246 . 88 ns 441 . 81 ns █▃▃▃▃▂▂▁▁▁
new Array ( 1024 ) 364 . 93 ns /iter 466 . 91 ns 600 . 34 ns █▄▁▁▁▅▅▃▂▁
Array . from ( 1 ) 29 . 73 ns /iter 29 . 24 ns 36 . 88 ns ▁█▄▃▂▁▁▁▁▁
Array . from ( 8 ) 33 . 96 ns /iter 32 . 99 ns 42 . 45 ns ▂█▄▂▂▁▁▁▁▁
Array . from ( 64 ) 146 . 52 ns /iter 143 . 82 ns 310 . 93 ns █▅▁▁▁▁▁▁▁▁
Array . from ( 512 ) 1 . 11 µs /iter 1 . 18 µs 1 . 34 µs ▃▅█▂▆▅▄▂▂▁
Array . from ( 1024 ) 1 . 98 µs /iter 2 . 09 µs 2 . 40 µs ▃█▃▃▇▇▄▂▁▁
summary
new Array ( $len )
5 . 42 … 8 . 33 x faster than Array . from ( $len )
┌ ┐
Array . from ( $size ) ⢠⠊
new Array ( $size ) ⢀⠔⠁
⡠⠃
⢀⠎
⡔⠁
⡠⠊
⢀⠜
⡠⠃
⡔⠁
⢀⠎
⡠⠃
⢀⠜
⢠⠊ ⣀⣀⠤⠤⠒
⡰⠁ ⣀⡠⠤⠔⠒⠊⠉
⣀⣀⣀⠤⠜ ⣀⡠⠤⠒⠊⠉
⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣔⣒⣒⣊⣉⠭⠤⠤⠤⠤⠤⠒⠊⠉
└ ┘
Caso você não precise de todo o material que vem com o mitata ou apenas precise de resultados brutos, o mitata exporta seus blocos de construção fundamentais para permitir que você construa facilmente suas próprias ferramentas e invólucros sem perder nenhum dos principais benefícios do uso do mitata.
# include " src/mitata.hpp "
int main () {
auto stats = mitata::lib::fn ([]() { /* * */ })
}
import { B , measure } from 'mitata' ;
// lowest level for power users
const stats = await measure ( function * ( state ) {
const size = state . get ( 'x' ) ;
yield ( ) => new Array ( size ) ;
} , {
args : { x : 1 } ,
batch_samples : 5 * 1024 ,
min_cpu_time : 1000 * 1e6 ,
} ) ;
// explore how magic happens
console . log ( stats . debug ) // -> jit optimized source code of benchmark
// higher level api that includes mitata's argument and range features
const b = new B ( 'new Array($x)' , state => {
const size = state . get ( 'x' ) ;
for ( const _ of state ) new Array ( size ) ;
} ) . args ( 'x' , [ 1 , 5 , 10 ] ) ;
const trial = await b . run ( ) ;
mitata ultrapassa os limites do javascript com loops de medição de sobrecarga zero gerados por jit para fornecer tempos de alta resolução. Isso permite fornecer recursos como frequência de clock da CPU e detecção de código morto sem exigir acesso fora da sandbox js.
clk : ~ 3 . 13 GHz
cpu : Apple M2 Pro
runtime : node 22 . 8 . 0 ( arm64-darwin )
benchmark avg ( min … max ) p75 p99 ( min … top 1 % )
-------------------------------------- -------------------------------
noop 93 . 09 ps /iter 91 . 55 ps █ !
( 61.04 ps … 20 . 30 ns ) 101 . 81 ps ▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁█▁▁▁▁▂
! = benchmark was likely optimized out ( dead code elimination )
// vs other libraries
16041 . 00 ns /iter - node : perf_hooks ( performance . timerify )
5.30 ns/iter - https : //npmjs . com /benchmark
noop x 188 , 640 , 251 ops/sec ± 5 . 71 % ( 73 runs sampled )
36 . 62 ns /iter - vitest bench / https : //npmjs . com / tinybench
┌─────────┬───────────┬──────────────┬───────────────────┬──────────┬──────────┐
│ ( index ) │ Task Name │ ops/sec │ Average Time ( ns ) │ Margin │ Samples │
├─────────┼───────────┼──────────────┼───────────────────┼──────────┼──────────┤
│ 0 │ ' noop ' │ ' 27 , 308 , 739 ' │ 36 . 61831406333669 │ ' ± 0 . 14 % ' │ 13654370 │
└─────────┴───────────┴──────────────┴───────────────────┴──────────┴──────────┘
156.5685 ns/iter - https : //npmjs . com /cronometro
╔══════════════╤═════════╤═══════════════════╤═══════════╗
║ Slower tests │ Samples │ Result │ Tolerance ║
╟──────────────┼─────────┼───────────────────┼───────────╢
║ Fastest test │ Samples │ Result │ Tolerance ║
╟──────────────┼─────────┼───────────────────┼───────────╢
║ noop │ 10000 │ 6386980 . 78 op /sec │ ± 1 . 85 % ║
╚══════════════╧═════════╧═══════════════════╧═══════════╝