[email protected]: big benchmark regression on block_on

Created on 9 May 2020  路  10Comments  路  Source: async-rs/async-std

In this PR https://github.com/casbin/casbin-rs/pull/136, I upgraded async-std to 1.6-beta.1 because I'm interested in its wasm support, thanks for @dignifiedquire who made the fix in branch fix/file-block https://github.com/async-rs/async-std/pull/768

However, after upgrading, I found that there is a big bench regression, you should be able to see it from here:

https://travis-ci.org/github/casbin/casbin-rs/jobs/685015785#L813

Most helpful comment

@algesten In that case, I wonder why not just use smol::run() to run it on the current thread?

Version 0.2 will break smol into 3 subcrates: blocking (already done), async I/O + timers, and executor. There will be more knobs for async I/O and executors, which will allow us to implement block_on() in async-std more efficiently.

All 10 comments

bench code: https://github.com/casbin/casbin-rs/blob/master/benches/benchmark.rs, this bench code isn't that correct because I'm creating runtime in every bench iter. I'm not able to solve it because of: #749 and https://github.com/async-rs/async-attributes/issues/9

However, casbin-rs's previous version uses the same bench code so basically I think the bench can be compared to previous version which uses [email protected]

@dignifiedquire Any idea on this? Thanks in advance.

@GopherJ it may also be useful to open an issue on smol since most of the runtime logic now lives there.

@yoshuawuyts From stjepang :

I believe because async-std's block_on currently starts a smol worker rather than just blocking on a future. This is currently a hack necessary to make spawning thread-local tasks within block_on possible.

then it becomes hard to benchmark async code. block_on will influence the result a lot

I am working on this, the issue will be fixed with smol 0.2 when it gets released. The solution is to create a thread-local executor lazily on demand. If there is no spawn_local() inside block_on(), there is no reason to initialize a thread-local executor.

@stjepang does that mean smol 0.2 block_on will semantically be closer to old async-std and tokio? i.e. in a single threaded runtime, it uses the local thread?

i would like to use smol, but i'm currently struggling cause my simplest case is a block_on that i don't want to spawn any new threads to drive, just use the current.

@algesten In that case, I wonder why not just use smol::run() to run it on the current thread?

Version 0.2 will break smol into 3 subcrates: blocking (already done), async I/O + timers, and executor. There will be more knobs for async I/O and executors, which will allow us to implement block_on() in async-std more efficiently.

@stjepang ah you're right! thanks! I'm just getting acquainted with smol's API. run is indeed what i'm after.

Is this still an issue? I believe it has been resolved but can we check?

HI, @stjepang , I confirm it's nearly fixed:

#![feature(test)]

extern crate test;

use test::Bencher;

fn raw_enforce(r: [&str; 3]) -> bool {
    let policies = [["alice", "data1", "read"], ["bob", "data2", "write"]];
    for policy in &policies {
        if policy == &r {
            return true;
        }
    }
    return false;
}

async fn async_enforce(r: [&str; 3]) -> bool {
    raw_enforce(r)
}

#[bench]
fn b_benchmark_raw(b: &mut Bencher) {
    b.iter(|| {
        raw_enforce(["alice", "data1", "read"]);
    });
}

#[bench]
fn b_benchmark_async(b: &mut Bencher) {
    b.iter(|| {
        async_std::task::block_on(async_enforce(["alice", "data1", "read"]));
    });
}

[email protected]

image

[email protected]

image

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oblique picture oblique  路  5Comments

yoshuawuyts picture yoshuawuyts  路  8Comments

zys864 picture zys864  路  4Comments

yoshuawuyts picture yoshuawuyts  路  6Comments

yoshuawuyts picture yoshuawuyts  路  3Comments