-
Notifications
You must be signed in to change notification settings - Fork 154
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
Add support for PHF in EnumString #220
Conversation
I'm using this fork on an enum with ~250 variants (all the same length) and observe extremely significant performance improvements. |
Tests fail due to #219 (unrelated to this PR) |
Hello @Ten0, thanks for the PR. I think the general idea makes perfect sense. It should be a nice performance win for some cases. Let me clarify a few things so I understand all the ramifications:
|
And I'll work on getting the doc tests fixed. |
I opted for not having that and letting the user bring the version of PHF they would want in scope, but that would also be an option. Although less flexible, that would probably be more stable. If doing this, that raises another question: if the
That is correct, I have neglected this part. It actually probably wouldn't be too hard to implement: we could lowercase both the arms and the string as it comes in I guess.
That's part of the reason why I didn't include it as a feature, but yes if we do we should definitely do that :) I'll move forward on this feature+ opt dep today or tomorrow. |
Comments applied :) |
Thanks for the updates! I triggered a new build. I think there are a few things failing in the 1.32 build.
I see that adding code to make phf with compatible complicated quite a few code paths. I wonder if it's best to in the initial version of this feature say phf is not compatible with case insensitive comparisons. |
Follow up thought on the phf + equality testing. I think the right compromise between performance and flexibility may be to do something like this: pub fn from_str(s: &str) -> MyEnum {
static PHF = map ! { .. };
if let Some(value) = PHF.get(s) {
return value;
}
match s {
s if s.ascii_eq_caseinsensitive("my_variant") => MyEnum::MyVariant,
_ => Err(NotFound),
}
} |
That is OK for my use-case at the moment as I don't need case insensitive parsing. In that case perhaps we should just use the feature flag to determine whether to use phf? This would make the interface significantly simpler. |
I think that makes sense. We'll just enable it automatically for anyone who enables the feature flag. In the future, there's a reasonable path for case-insensitive parsing where we add both the lowercase and uppercase versions of the text to the map as an optimization and then more complicated cases still fallback to the match statement. |
Turns out the requirement on So I think this is generally ready.
That would be the only thing left to do I think - I've prepared the feature in the tests crate, so it looks like we only need to do the (almost) equivalent of https://github.com/diesel-rs/diesel/blob/50c2c85032857a65e4a8d68dc851fa7ab91d65b2/.github/workflows/ci.yml#L234 here. You should have push access, as I have checked the "Allow edits by maintainers" box. :) |
Thanks for the last round of changes. I went ahead and did the merge, and I'll just open a second PR to fix the build. I'm also going to benchmark the lowercase logic a little bit and potentially tweak/update it. Thanks for your help on this feature!! |
Published to crates.io as version 0.24.1 |
@Ten0, I had to temporarily yank 0.24.1 from crates :(. It was released along with #217 which caused more breaking changes than I was happy with. I'm sorry for the inconvenience, and I'm working on getting it re-released, but I wanted to get the incompatible version down before additional people took a dependency on it. thank you for understanding. |
Thanks for the warning, we reverted to the fork on our system |
Okay 0.24.2 is published which contains phf support and reverted the other change. |
Resolves #218
Via an additional
use_phf
attribute at the enum metadata level.