bun add mitata
npm install mitata
coba mitata di browser dengan asisten ai di https://bolt.new/~/mitata
node --expose-gc ...
)javascript | c++ tajuk tunggal |
---|---|
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 ( ".*" ) } ) ;
Pada runtime yang mengekspos gc (misalnya bun, node --expose-gc ...
), mitata akan secara otomatis menjalankan pengumpulan sampah sebelum setiap benchmark.
Perilaku ini dapat disesuaikan lebih lanjut melalui fungsi gc
pada setiap benchmark (Anda hanya boleh melakukan ini jika benar-benar diperlukan - lonjakan gc yang besar):
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' ) ;
Mitata yang siap pakai dapat mendeteksi mesin/runtime yang sedang berjalan dan kembali menggunakan fungsi I/O non-standar alternatif. Jika mesin atau runtime Anda tidak memiliki dukungan, buka masalah atau mintalah dukungan.
$ 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
Dengan pustaka pembandingan lainnya, sering kali cukup sulit untuk dengan mudah membuat tolok ukur yang mencakup rentang tertentu atau menjalankan fungsi yang sama dengan argumen berbeda tanpa menulis kode spaghetti, namun sekarang dengan mitata, mengonversikan tolok ukur Anda untuk menggunakan argumen hanya dengan memanggil fungsi saja.
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
Untuk kasus di mana Anda memerlukan salinan nilai unik untuk setiap iterasi, mitata mendukung pembuatan parameter komputasi yang tidak diperhitungkan dalam hasil benchmark (catatan: tidak ada jaminan penghitungan ulang waktu, pesanan, atau jumlah panggilan) :
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
didukung di: macos (apple silicon) | linux (amd64, aarch64)
Dengan menginstal paket @mitata/counters
Anda dapat mengaktifkan pengumpulan dan tampilan penghitung perangkat keras untuk benchmark.
------------------------------------------- -------------------------------
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 )
Bagi mereka yang suka melakukan mikro-benchmark, mitata dapat secara otomatis mendeteksi dan memberi tahu Anda tentang proses pengoptimalan seperti penghapusan kode mati tanpa memerlukan tanda mesin khusus.
-------------------------------------- -------------------------------
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 )
dengan kemampuan rendering ascii mitata, kini Anda dapat dengan mudah memvisualisasikan sampel dalam barplot, boxplot, lineplot, histogram, dan mendapatkan ringkasan yang jelas tanpa alat atau ketergantungan tambahan apa pun.
-------------------------------------- -------------------------------
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 ) ⢀⠔⠁
⡠⠃
⢀⠎
⡔⠁
⡠⠊
⢀⠜
⡠⠃
⡔⠁
⢀⠎
⡠⠃
⢀⠜
⢠⠊ ⣀⣀⠤⠤⠒
⡰⠁ ⣀⡠⠤⠔⠒⠊⠉
⣀⣀⣀⠤⠜ ⣀⡠⠤⠒⠊⠉
⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣔⣒⣒⣊⣉⠭⠤⠤⠤⠤⠤⠒⠊⠉
└ ┘
Jika Anda tidak membutuhkan semua hal yang disertakan dengan mitata atau hanya membutuhkan hasil mentah, mitata mengekspor blok bangunan fundamentalnya untuk memungkinkan Anda dengan mudah membuat perkakas dan pembungkus Anda sendiri tanpa kehilangan manfaat inti menggunakan 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 mendorong batas javascript dengan loop pengukuran zero-overhead yang dihasilkan jit untuk menyediakan pengaturan waktu resolusi tinggi. Hal ini memungkinkan penyediaan fitur seperti frekuensi jam cpu dan deteksi kode mati tanpa memerlukan akses di luar js sandbox.
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 % ║
╚══════════════╧═════════╧═══════════════════╧═══════════╝