-
-
Notifications
You must be signed in to change notification settings - Fork 77
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
Improve casbin-rs bench #109
Comments
Pay attention that the bench here is all about enforcing. |
See also : rhaiscript/rhai#101 |
https://casbin.org/casbin-rs/dev/bench/ You can visualize it here. Seems actions took 1h30m to finish all the bench. There must be a problem somewhere. UPDATE It took 1h30m because I had a mistake on bench code, now it's ok.... |
We can first try https://github.com/flamegraph-rs/flamegraph to see where is the bottleneck. |
@GopherJ |
@hackerchai You can run it through:
there is no action benchmark graph on casbin golang |
@GopherJ Get it |
@xcaptain are you able to generate a graph using: https://github.com/casbin-rs/casbin-flamegraph ? I failed to generate |
Basically I have no idea why Also while checking the source of I think most of the lost time is on creating UPDATE
|
I generated a simple graph from the if we use casbin-rs/benches/benchmark.rs Line 143 in 71f93f3
If we do |
using await in loop is ok, but block_on will sadly libtest bencher and criterion don't support executor out of box. |
I'm sure the let mut engine = Engine::new();
let mut scope: Scope = Scope::new(); but because of lifetime stuff and I do agree with @GopherJ that comparing |
Yes rhai's benchmark is worser than govaluate. With the latest commit, casbin golang is 6x ~ 7x faster than casbin-rs including the fact that rhai is slower and we are repeatedly creating async-std runtime in every b.iter. It's ok for me. Maybe we can try to share engine because it seems creating a new Engine while enforcing is a little bit heavy as flamegraph shows. And eventually see how to improve rhai's benchmark. |
I completely agree although I wasn't able to get that to work. The only other idea I had would be passing a
|
@DevinR528 Why not add directly another field in enforcer? I think it's ok. |
I propose you guys to check the code and see what you can improve! Uses https://github.com/BurntSushi/cargo-benchcmp to see the changes |
I did try adding it as a field they both (Scope and Engine) have lifetimes, that makes the Creating a
|
Really I agree to take some actions to improve |
No you are right it does add some overhead this is the same function just with async keyword and being awaited by
What I mean about the flamegraph is that since it measures everything in relation to the time each function took to run the |
The latest bench from my rust
Go version is around 3 - 5 times faster including |
It seems
Even I already removed many built in functions and the engine doesn't need to register them during runtime but still there are many functions registered during runtime |
share engine is done #117 and the rest possibilities of benchmark improvements should be on rhai side instead of casbin-rs |
@GopherJ @hackerchai we should find out what part of rhai is slow, I saw you made some progress in discussion here: rhaiscript/rhai#101 . Rust is supposed to be at least 10x faster than Golang. Being even slower than Golang is not understandable. Or is there any other Rust expression evaluators that runs fast? |
@hsluoyz It'll be a long story to improve the bench. Yes it tends to be faster and the Including like I mentioned in this issue, the code we used to benchmark isn't that correct, we didn't remove the time of creating async executor. Then rhai is slower than govaluate, basically in my opinion rhai has a pretty large prospective, we can nearly implement everything that a language has in rhai. like (threads, promise etc...). But based on this view, it's not efficient enough, I read some of their code but I cannot help too much because I didn't a compiler-principle background. But to improve the bench, I'll continue to read their code and see if I can help |
https://github.com/casbin/casbin-rs/blob/master/src/enforcer.rs#L108-L111 May I suggest that you create a custom package initialized by the four sub-packages and share it. Then you only have to register one package each time a scripting engine is created. Having one large package improves speed because a function needs not be searched in four different places.
The above creates |
There is an effort on-going to compile Rhai scripts into bytecodes. Hopefully that'll make it faster... |
Well, my opinion is that, it is never too early to make API's My suggestion is to keep |
@schungx The only part which needs to think about this problem is I have change them back to Currently we already have |
Yeah, that sounds sound. :-) I'm still trying out a few optimizations on the Rhai side. Will open up a PR in a bit. |
Ok thanks @schungx. Looking forward to seeing your optimizations:) |
Also if rust-lang/rust#72078 get solved then |
What you want should not be possible. That's why the Rust standard library is sprinkled with tons of |
PR #165 opened, but somehow it is including all the commits from my previous PR... no idea what's going on. But anyhow, the last commit is the right one. |
async vs sync before:
seems |
tokio will be totally another thing because tokio's before:
|
Does it mean that we're finally close to Go speed? That's a good start... the next goal is to be faster... BTW, can you pull from my latest in https://github.com/schungx/rhai This version implements most of the common operators for standard types as a fast-track. For |
Hi @schungx , it's already close but |
@schungx I did a bench using your master, the result is quite similar
|
Well, it improves speed 10% for scripts heavy in numerical and logical operators... The one major thing on the table that I haven't been able to resolve is the need to copy values. Normally, it is fine for numbers and booleans etc. For For example, a simple
My next experiment is to intern all Rhai strings into |
Turns out it is extremely easy to make all strings immutable in Rhai, and get rid of all cloning/copying. Can you pull from my latest to test it out? Make sure you change this in lib.set_fn_1("escape_assertion", |mut s: rhai::ImmutableString| {
Arc::make_mut(&mut s);
Ok(Arc::try_unwrap(s).unwrap())
}); because Rhai now works with immutable strings. Unfortunately I can no longer compile |
@schungx To compile, you can downgrade all |
Doesn't work. Still tries to pull in |
OK, need to switch the default toolchain to Using It is a bummer as the GNU toolchain seems to generate faster code for Windows... |
@GopherJ please check out #168 It uses the latest version of Rhai which uses immutable strings internally to avoid copying. I get these results running on my computer: Before: 0.14.1
|
@schungx Yes the CI passed on windows so normally it should work, the numbers look awesome! |
@schungx I see a significant bench improvement on [email protected], will upgrade on casbin-rs side soon
bravo! This bench is already similar to golang's version |
@GopherJ since you've turned the Do you find the async API to be slower, when called in a sync manner (perhaps via Do you feel justified in moving the API from sync to async? |
@schungx async can only be useful for IO operation like: network connection. casbin-rs has db adapters so I think async is necessary,it helps the situation where many policies changes are necessary If we call async in sync manner, certainly it'll be slower,even rust has some zero cost abstractions,still at least a Poll is necessary. |
Thanks... that's what I thought. Do you have any benchmark data on sync vs async and how much of a slowdown it is? I can see from your previous data that |
@schungx Hi, However, currently b.bench_async_using_executor(tokio_executor, async move {
...
}) see also: rust-lang/rust#71186 that means, starts from fn main() {
async_std::block_on(async move {
// a multi-threaded executor
// we can spawn tasks on this executor
// it's always the same executor, not like bench code which create a new executor in every iteration
});
} |
As per the |
@schungx yes sure |
currently casbin-rs has already better performance than casbin-golang, thanks to @schungx for all the support that you've made. It's time to close this issue. |
While doing the same bench test suite like casbin golang: https://github.com/casbin/casbin/blob/master/model_b_test.go
I found we can get similar results with
CachedEnforcer
but the normal enforcer is 6x ~ 7x slower than golang version.Can someone help investigating?
@xcaptain @DevinR528 @PsiACE @hackerchai
eg. running
small size of rbac model test
:Casbin Golang
Casbin Rust
Ref
The text was updated successfully, but these errors were encountered: