Deno: Plugin Op call time

Created on 28 Jul 2020  Β·  8Comments  Β·  Source: denoland/deno

One Op call for custom rust plugin takes ~10989ns based on my test project:
https://github.com/playerx/deno-rust-plugin

Next I've compared it to the Nodejs C++ bindings (Napi) and result is ~341ns based on another test project:
https://github.com/playerx/nodejs-cpp-binding

Do you plan to improve op call time? Also it will be useful if there will be benchmark about it somewhere on the Deno benchmark page.

P.S. This is my first rust code in the test project, please let me know if there is a way to improve the performance.

Most helpful comment

Haven't run any tests yet, but here's another obversation:

performance.now() is also an op/binding that calls into native code. If ops in Deno are slower than bindings in Node, the current benchmark setup may be skewed since it's testing the performance of 3 ops/bindings rather than just 1. To check whether this has an impact, you could take the time before the loop and after to calculate the average, e.g.:

let start = performance.now();
for (let i = 0; i < sample_size; i++) {
  // call op/binding here
}
let end = performance.now();

All 8 comments

~1ms~ 0.01ms (more or less) per call is very bad... I really hope it's not true.

So for starters I would suggest to build the plugin with "cargo build --release". Currently you're benchmarking a debug build.

Tried out a release build on Ubuntu.

deno run --allow-plugin --unstable --allow-hrtime mod.ts
Check file:///home/caspervonb/deno-rust-plugin/mod.ts
Custom Ops
β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (idx) β”‚        0        β”‚       1        β”‚        2        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   0   β”‚ "custom plugin" β”‚ "customSyncOp" β”‚ "customAsyncOp" β”‚
β”‚   1   β”‚        3        β”‚       83       β”‚       84        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


Pure Sync Op call duration (ms)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (idx) β”‚          0           β”‚          1           β”‚         2          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   0   β”‚        "Min"         β”‚        "Avg"         β”‚       "Max"        β”‚
β”‚   1   β”‚ 0.004852000000028056 β”‚ 0.007713939000000132 β”‚ 1.7817680000000564 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Thanks for the feedback, I've applied the changes and now I have the following results:
Avg - 9820ns
Fastest - 6649ns

_Note: Updated repo as well_

Found one related PR:
https://github.com/denoland/deno/pull/3505

Haven't run any tests yet, but here's another obversation:

performance.now() is also an op/binding that calls into native code. If ops in Deno are slower than bindings in Node, the current benchmark setup may be skewed since it's testing the performance of 3 ops/bindings rather than just 1. To check whether this has an impact, you could take the time before the loop and after to calculate the average, e.g.:

let start = performance.now();
for (let i = 0; i < sample_size; i++) {
  // call op/binding here
}
let end = performance.now();

@MarkTiedemann you are right, after changing it the way you've described we have result ~319ns per op call

Also applied same change to the nodejs project and it needs ~184ns to call Napi binding and return result back

_Note: Repos are updated_

@playerx I’m glad you’re raising this topic

We should add a benchmark like this to http://deno.land/benchmarks?-300

I think nodejs sample should also be changed to use for loop instead of Array.map.

@leoc11 Good catch, Thanks. Now it's 167ns for node.js

@ry Great, I can create PR for this benchmark. I like the benchmark site Deno has and want to check the way it is implemented anyways

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ry picture ry  Β·  3Comments

ry picture ry  Β·  3Comments

zugende picture zugende  Β·  3Comments

davidbarratt picture davidbarratt  Β·  3Comments

somombo picture somombo  Β·  3Comments