Skip to content

Commit 2fb9145

Browse files
author
Markus Westerlind
committed
Add combine based benchmark to catch exponential regression
1 parent 48d49d2 commit 2fb9145

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

collector/benchmarks/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,4 @@ programs.
9595
- **wf-projection-stress-65510**: A stress test which showcases [quadratic
9696
behavior](https://github.com/rust-lang/rust/issues/65510) (in the number of
9797
associated type bounds).
98+
- **trait-stress-68666**: A stress test which constructs a parser in the same manner that `combine` does. Showcases [exponential behavior](https://github.com/rust-lang/rust/issues/68666) in trait selection.

collector/benchmarks/trait-stress/Cargo.lock

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "combine"
3+
version = "0.1.0"
4+
authors = ["Markus Westerlind <[email protected]>"]
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
10+
[workspace]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::marker::PhantomData;
2+
3+
pub trait Parser<Input> {
4+
type Output;
5+
6+
fn or<P2>(self, p: P2) -> Or<Self, P2>
7+
where
8+
Self: Sized,
9+
P2: Parser<Input, Output = Self::Output>,
10+
{
11+
Or(self, p)
12+
}
13+
}
14+
15+
#[macro_export]
16+
macro_rules! choice {
17+
($first : expr) => {
18+
$first
19+
};
20+
($first : expr, $($rest : expr),+) => {
21+
$first.or(choice!($($rest),+))
22+
}
23+
}
24+
25+
pub struct Or<P1, P2>(P1, P2);
26+
impl<Input, P1, P2> Parser<Input> for Or<P1, P2>
27+
where
28+
P1: Parser<Input, Output = P2::Output>,
29+
P2: Parser<Input>,
30+
{
31+
type Output = P2::Output;
32+
}
33+
34+
pub struct P<I, O>(PhantomData<fn(I) -> O>);
35+
impl<Input, O> Parser<Input> for P<Input, O> {
36+
type Output = O;
37+
}
38+
39+
pub fn token<I>(_: u8) -> impl Parser<I, Output = u8> {
40+
P(PhantomData)
41+
}
42+
43+
fn mcc_payload_item<I>() -> impl Parser<I, Output = u8> {
44+
choice!(
45+
token(b'G'),
46+
token(b'G'),
47+
token(b'G'),
48+
token(b'G'),
49+
token(b'G'),
50+
token(b'G'),
51+
token(b'G'),
52+
token(b'G'),
53+
token(b'G'),
54+
token(b'G'),
55+
token(b'G'),
56+
token(b'G'),
57+
token(b'G'),
58+
token(b'G'),
59+
token(b'G'),
60+
token(b'G')
61+
)
62+
}
63+
64+
fn main() {}

0 commit comments

Comments
 (0)