Skip to content

Make match_ignore_ascii_case more efficient, add ascii_case_insensitive_phf_map #122

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

Merged
merged 14 commits into from
Feb 25, 2017

Conversation

SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Feb 25, 2017

This improves the performance of match_ignore_ascii_case! by replacing calls to str::eq_ignore_ascii_case with plain string equality. The input string is converted to ASCII lower-case once, using a stack allocated buffer. A proc_macro_derive is used internally to ensure that string patterns are already lower-case, and to computed the size of the buffer (the length of the longest pattern).

This should improve runtime performance, it the amount of generated MIR or LLVM IR in release mode still looks proportional to the number of patterns, so this by itself won’t help much with the code bloat in parse_color_keyword.

To deal with that, this PR also adds a ascii_case_insensitive_phf_map! macro that reuses the same stack-allocated buffer mechanism to lower-case an input string, and combines it with a phf static hash map.

The two macros are similar but make different treadoffs. PHF probably generates faster and less bloated code, but the map’s values need to be given as a string that contains Rust syntax, due to limitations of procedural macros in current stable Rust. On the other hand, generating a match expression allows using control flow statements like return or continue in its match arms.

Fixes #115.


This change is Reviewable

Previously, the compiler would emit many `eq_ignore_ascii_case` calls,
leading to code bloat and probably some slowness.

Now, we pre-lowercase the input in a stack-allocated buffer
then match exact strings.
Hopefully, the optimizer can turn this into a static table and a loop.
Let users pass a `&foo` borrow. `&Cow<str>` can auto-deref to `&str`.
…f_map!

We can do the lower-casing at compile time in a proc-macro.

Note that `match_ignore_ascii_case!` still has that requirement,
since it’s `macro_rules!` that generates a `match` expression.
* String patterns now need to be already ASCII lower-case
* Input string is no longer implicitly borrowed, add `&` as needed.
@SimonSapin
Copy link
Member Author

SimonSapin commented Feb 25, 2017

r? @Manishearth, CC @nox

Do not merge just yet, I’ll make sure Servo can build with this first :) Done.

bors-servo pushed a commit to servo/servo that referenced this pull request Feb 25, 2017
Update cssparser to 0.11

<!-- Please describe your changes on the following line: -->

Depends on servo/rust-cssparser#122.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Copy link
Member

@Manishearth Manishearth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me looks good. Can't wait for proper proc macro support.

@SimonSapin
Copy link
Member Author

@bors-servo r=Manishearth

@bors-servo
Copy link
Contributor

📌 Commit 136c97a has been approved by Manishearth

@bors-servo
Copy link
Contributor

⌛ Testing commit 136c97a with merge ded474a...

bors-servo pushed a commit that referenced this pull request Feb 25, 2017
Make match_ignore_ascii_case more efficient, add ascii_case_insensitive_phf_map

This improves the performance of `match_ignore_ascii_case!` by replacing calls to `str::eq_ignore_ascii_case` with plain string equality. The input string is converted to ASCII lower-case once, using a stack allocated buffer. A `proc_macro_derive` is used internally to ensure that string patterns are already lower-case, and to computed the size of the buffer (the length of the longest pattern).

This should improve runtime performance, it the amount of generated MIR or LLVM IR in release mode still looks proportional to the number of patterns, so this by itself won’t help much with the code bloat in `parse_color_keyword`.

To deal with that, this PR also adds a `ascii_case_insensitive_phf_map!` macro that reuses the same stack-allocated buffer mechanism to lower-case an input string, and combines it with a [`phf`](https://github.com/sfackler/rust-phf) static hash map.

The two macros are similar but make different treadoffs. PHF probably generates faster and less bloated code, but the map’s values need to be given as a string that contains Rust syntax, due to limitations of procedural macros in current stable Rust. On the other hand, generating a `match` expression allows using control flow statements like `return` or `continue` in its match arms.

Fixes #115.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-cssparser/122)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

💔 Test failed - status-travis

@SimonSapin
Copy link
Member Author

@bors-servo retry

Job timed out.

@bors-servo
Copy link
Contributor

⌛ Testing commit 136c97a with merge 89115eb...

bors-servo pushed a commit that referenced this pull request Feb 25, 2017
Make match_ignore_ascii_case more efficient, add ascii_case_insensitive_phf_map

This improves the performance of `match_ignore_ascii_case!` by replacing calls to `str::eq_ignore_ascii_case` with plain string equality. The input string is converted to ASCII lower-case once, using a stack allocated buffer. A `proc_macro_derive` is used internally to ensure that string patterns are already lower-case, and to computed the size of the buffer (the length of the longest pattern).

This should improve runtime performance, it the amount of generated MIR or LLVM IR in release mode still looks proportional to the number of patterns, so this by itself won’t help much with the code bloat in `parse_color_keyword`.

To deal with that, this PR also adds a `ascii_case_insensitive_phf_map!` macro that reuses the same stack-allocated buffer mechanism to lower-case an input string, and combines it with a [`phf`](https://github.com/sfackler/rust-phf) static hash map.

The two macros are similar but make different treadoffs. PHF probably generates faster and less bloated code, but the map’s values need to be given as a string that contains Rust syntax, due to limitations of procedural macros in current stable Rust. On the other hand, generating a `match` expression allows using control flow statements like `return` or `continue` in its match arms.

Fixes #115.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-cssparser/122)
<!-- Reviewable:end -->
@SimonSapin
Copy link
Member Author

Not sure what homu is doing, https://travis-ci.org/servo/rust-cssparser/builds/205343338 is green.

@SimonSapin SimonSapin merged commit 4890542 into master Feb 25, 2017
@SimonSapin SimonSapin deleted the macros branch February 25, 2017 19:36
bors-servo referenced this pull request in servo/servo Feb 25, 2017
Update cssparser to 0.11

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15735)
<!-- Reviewable:end -->
bors-servo referenced this pull request in servo/servo Feb 25, 2017
Update cssparser to 0.11

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15735)
<!-- Reviewable:end -->
bors-servo referenced this pull request in servo/servo Feb 26, 2017
Update cssparser to 0.11

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15735)
<!-- Reviewable:end -->
moz-v2v-gh referenced this pull request in mozilla/gecko-dev Feb 26, 2017
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : b6f18aa92334574e0874e2ce8505c03f295c7d49
@nox nox mentioned this pull request Feb 27, 2017
4 tasks
JerryShih referenced this pull request in JerryShih/gecko-dev Mar 1, 2017
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172
Manishearth referenced this pull request in Manishearth/gecko-dev Mar 9, 2017
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172
@SimonSapin SimonSapin mentioned this pull request Jun 25, 2017
gecko-dev-updater referenced this pull request in marco-c/gecko-dev-comments-removed Oct 1, 2019
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172

UltraBlame original commit: 6fec46f1729153a0e230f4dac07ba776eebe6102
gecko-dev-updater referenced this pull request in marco-c/gecko-dev-wordified Oct 1, 2019
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172

UltraBlame original commit: 6fec46f1729153a0e230f4dac07ba776eebe6102
gecko-dev-updater referenced this pull request in marco-c/gecko-dev-wordified-and-comments-removed Oct 1, 2019
…p); r=emilio

<!-- Please describe your changes on the following line: -->

<s>Depends on https://github.com/servo/rust-cssparser/pull/122.</s>

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94e563e4d9292d7b19ce061e070cda358e822172

UltraBlame original commit: 6fec46f1729153a0e230f4dac07ba776eebe6102
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

Successfully merging this pull request may close these issues.

3 participants