Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support llrt bench command #586

Open
ahaoboy opened this issue Sep 12, 2024 · 5 comments
Open

Support llrt bench command #586

ahaoboy opened this issue Sep 12, 2024 · 5 comments

Comments

@ahaoboy
Copy link
Contributor

ahaoboy commented Sep 12, 2024

When I want to compare the performance of some functions, it would be convenient if it could support a bench api like vitest

vitest is a bit too complicated. I tried running tinnybench, but it failed because it lacked the Event class.

https://github.com/tinylibs/tinybench
https://nodejs.org/api/events.html#class-event

@richarddavison
Copy link
Contributor

Event and EventTarget should be in LLRT as per WinterCG. Here is a basic polyfil for them that can be used as a basis for implementation:
https://github.com/mysticatea/event-target-shim/

Simplest implementation would be to extend features here:
https://github.com/awslabs/llrt/blob/llrt_modules/src/modules/events/event_target.rs

@ahaoboy
Copy link
Contributor Author

ahaoboy commented Sep 14, 2024

Event and EventTarget should be in LLRT as per WinterCG. Here is a basic polyfil for them that can be used as a basis for implementation: https://github.com/mysticatea/event-target-shim/

After adding the polyfill, it does work. Interestingly, SIMD on Windows and Ubuntu does not seem to perform as well as the original qjs version.

small json
https://github.com/awslabs/llrt/blob/main/package.json
big json
https://github.com/simdjson/simdjson/blob/master/jsonexamples/twitter.json

// npm install event-target-shim
import { EventTarget, Event } from "event-target-shim";

globalThis.Event = Event
globalThis.EventTarget = EventTarget

import { Bench } from 'tinybench';

const bench = new Bench({ time: 100 });

import mod from './a.json'

async function main() {
  bench
    .add('simd', () => {
      SIMD_JSON.stringify(mod)
    })
    .add('json', async () => {
      JSON.stringify(mod)
    })
  await bench.warmup();
  await bench.run();
  console.log(bench.table());
}

main()
[ {
    Task Name: 'simd',
    ops/sec: '12863',
    Average Time (ns): 77739.62703962662,
    Margin: '±0.93%',
    Samples: 1287
  }, {
    Task Name: 'json',
    ops/sec: '16808',
    Average Time (ns): 59492.50446162962,
    Margin: '±0.84%',
    Samples: 1681
  } ]

@nabetti1720
Copy link
Contributor

This is a bit off topic, but EventTarget seems to work without replacing polyfill.

// index4.js
import { Event } from "event-target-shim";

globalThis.Event = Event

import { Bench } from 'tinybench';

const bench = new Bench({ time: 100 });

import mod from '../package.json';

bench
  .add('json', async () => {
    JSON.stringify(mod)
  })
await bench.warmup();
await bench.run();
console.log(bench.table());
% npm run build4

> build4
> ./node_modules/.bin/esbuild ./src/index4.js --outfile=dist/index4.mjs --platform=node --target=es2023 --format=esm --bundle


  dist/index4.mjs  38.1kb

⚡ Done in 18ms

% npm run llrt4 

> llrt4
> llrt ./dist/index4.mjs

[ {
    Task Name: 'json',
    ops/sec: '151646',
    Average Time (ns): 6594.263105835792,
    Margin: '±0.16%',
    Samples: 15165
  } ]

@richarddavison
Copy link
Contributor

After adding the polyfill, it does work. Interestingly, SIMD on Windows and Ubuntu does not seem to perform as well as the original qjs version.

This is very strange. I got over 200% speedup when implemented SIMD JSON. Can you show me the code?

@ahaoboy
Copy link
Contributor Author

ahaoboy commented Sep 15, 2024

This is very strange. I got over 200% speedup when implemented SIMD JSON. Can you show me the code?

I found that I used debug mode for testing :(, and in release mode, simd is about 30% faster.

Maybe we can move the json module into llrt_modules as well

+    let json_module = Object::new(ctx.clone())?;
-   // let json_module: Object = globals.get(PredefinedAtom::JSON)?;


+    globals.set("SIMD_JSON", json_module)?;
// import mod from './small.json'
import mod from './big.json'

const str_json = JSON.stringify(mod)
const str_simd = SIMD_JSON.stringify(mod)
const N = 1000

function bench(fn) {
  const st = +Date.now()
  for (let i = 0; i < N; i++) {
    fn()
  }
  const ed = +Date.now()
  return ed - st
}

{
  const simd = bench(() => SIMD_JSON.stringify(mod))
  const json = bench(() => JSON.stringify(mod))

  console.log(
    'simd stringify: ', simd,
    'json stringify: ', json
  )
}

{
  const simd = bench(() => SIMD_JSON.parse(str_simd))
  const json = bench(() => JSON.parse(str_json))

  console.log(
    'simd parse: ', simd,
    'json parse: ', json
  )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants