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

Strategy does not implement Sync #12

Closed
vitiral opened this issue Nov 19, 2017 · 11 comments
Closed

Strategy does not implement Sync #12

vitiral opened this issue Nov 19, 2017 · 11 comments

Comments

@vitiral
Copy link

vitiral commented Nov 19, 2017

I'm not sure if there is a technical reason this is not possible, but I thought I would check.

I would like to create the regex strategy using lazy_static! but Strategies don't implement Sync.

Thanks!

error[E0277]: the trait bound `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static: std::marker::Sync` is not satisfied
  --> src/test_name.rs:38:1
   |
38 | / lazy_static!{
39 | |     static ref GEN_NAME_PROP: prop::string::RegexGeneratorStrategy<String> =
40 | |         prop::string::string_regex(GEN_NAME_RE).unwrap();
41 | | }
   | |_^ `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static` cannot be shared between threads safely
   |
   = help: the trait `std::marker::Sync` is not implemented for `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static`
   = note: required because of the requirements on the impl of `std::marker::Sync` for `std::ptr::Unique<proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String
> + 'static>> + 'static>`
   = note: required because it appears within the type `std::boxed::Box<proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static>`
   = note: required because it appears within the type `proptest::string::RegexGeneratorStrategy<std::string::String>`
   = note: required by `lazy_static::lazy::Lazy`
   = note: this error originates in a macro outside of the current crate

error: aborting due to previous error

error: Could not compile `artifact-data`.
@vitiral
Copy link
Author

vitiral commented Nov 19, 2017

also, any advice on speeding up generation of random strings? I'm seeing significant (i.e. 10x) slowdowns compared to quickcheck + regex_generate.

@vitiral
Copy link
Author

vitiral commented Nov 19, 2017

one thing I did: reduce the number generated for tests that don't need a large number. Very hard to do with quickcheck!

@AltSysrq
Copy link
Collaborator

Strategies don't implement Sync

I originally wanted to leave the possibility of using interior mutability within a strategy. But as I found out trying to implement prop_recursive with it, you can't usefull track state in a strategy anyway, so I don't think there's any reason not to add Sync at this point.

seeing significant (i.e. 10x) slowdowns compared to quickcheck + regex_generate

That's somewhat expected. Proptest needs to build and retain a more complicated structure for shrinking to work correctly. The generation could also benefit a lot from small string optimisation; currently, each individual element of the regex becomes its own Vec<u8>, so you may be paying for an enormous amount of allocations depending on the regex. I'll look into improving this soon.

@vitiral
Copy link
Author

vitiral commented Nov 20, 2017

Thanks for the replies. It would be nice to add Sync.

As for the slowdown, I think it's mostly fine -- obviously faster is always better :)

It would probably be worth documenting eventually though, especially if a solution cannot be found.

@AltSysrq
Copy link
Collaborator

It turns out that adding Strategy: Send + Sync would actually be pretty painful as combinators like prop_map would need to require the closures to be Send + Sync. Instead, I'm just fixing the immediate problem which was specific to the regex strategy, which used Box<Strategy> under the hood and so erased the OIBITS. I'm also adding a conventional way to make a Box<Strategy + Send + Sync> so external users can get the same benefit.

The only other remaining internal use of BoxedStrategy is in prop_recursive(), but I'm not sure what could be done there since switching to the Send + Sync version would restrict how people could use that combinator.

@AltSysrq
Copy link
Collaborator

@vitiral Would you be able to provide the regex in question? I started looking into optimising the string generation, but the regex I tried ([0-9]{4}-[0-9]{2}-[0-9]{2} .*) ended up being faster than I anticipated (~9μs per iteration), so it would help to have a slow-but-realistic test case.

@vitiral
Copy link
Author

vitiral commented Nov 30, 2017

Here is the regex I am using:

const GEN_NAME_RE: &str = r#"(?ix)
(REQ|SPC|TST)-              # the type followed by `-`
([a-z0-9_]{1,20}-){0,8}     # an optional number of `elem-` elements
[a-z0-9_]{1,20}             # required final element
"#;

@vitiral
Copy link
Author

vitiral commented Nov 30, 2017

originally I was using * instead of the ranges {1,20} or {0,8}. That was slow, so I adjusted the ranges to (I think) up to 50 and then down to 20/8.

Hope that helps!

@AltSysrq
Copy link
Collaborator

AltSysrq commented Dec 9, 2017

The various string-generation strategies are now Send + Sync as of 0.3.2.

I also did look into the performance of string generation, and I believe the main bottleneck is actually character generation due to the inefficient way it accomplishes biasing towards particular characters. Changing that will likely require breaking backwards compatibility, so I'll make another pass at that at a later time.

@AltSysrq
Copy link
Collaborator

AltSysrq commented Dec 9, 2017

I've moved the regex performance concerns to a separate issue (#16) since the problem referenced by the title of this one has been fixed.

@AltSysrq AltSysrq closed this as completed Dec 9, 2017
@vitiral
Copy link
Author

vitiral commented Dec 9, 2017

Thanks! Wow, you are really responsive on these issues. Hope they were helpful for you as a lib designer!

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

2 participants