Skip to content

Commit

Permalink
Replace regex with manual string split
Browse files Browse the repository at this point in the history
Summary:
I was doing typechecker, and since some recent changes (likely after D48295588), typechecker became much slower.

Instead of 7% overhead, it is 50% overhead.

I started looking at profiler.

```
    25.45%  buck2-rt         [kernel.kallsyms]     [k] queued_spin_lock_slowpath
```

Or the same from strobelight:

{F1072524306}

([1](https://fburl.com/strobelight/fihizjz9) [2](https://fburl.com/strobelight/8a55kesp))

Obtaining types using documentation is suboptimal. But I need to make it fast now to continue working on typechecker.

(Also reported to [regex issue tracker](rust-lang/regex#1066), but they are probably aware of it).

(We need to figure out how to work with regular expressions).

Reviewed By: iguridi

Differential Revision: D48496022

fbshipit-source-id: 5d8113ca014208ab5d1db1750f83792d02462cc5
  • Loading branch information
stepancheg authored and facebook-github-bot committed Aug 23, 2023
1 parent d7e5e2a commit 70990ec
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions starlark-rust/starlark/src/docs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,26 @@ impl DocString {
None
}

fn split_summary_details(s: &str) -> Option<(&str, &str)> {
let mut summary_len = 0;
for line in s.split_inclusive('\n') {
if line.trim().is_empty() {
let details_start = summary_len + line.len();
return Some((s[..summary_len].trim(), &s[details_start..]));
} else {
summary_len += line.len();
}
}
None
}

/// Do common work to parse a docstring (dedenting, splitting summary and details, etc)
pub fn from_docstring(kind: DocStringKind, user_docstring: &str) -> Option<DocString> {
let trimmed_docs = user_docstring.trim();
if trimmed_docs.is_empty() {
None
} else {
static SPLIT_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\n[ ]*\n").unwrap());
let split: Option<(&str, &str)> = SPLIT_RE.splitn(trimmed_docs, 2).collect_tuple();
let split: Option<(&str, &str)> = Self::split_summary_details(trimmed_docs);
let (summary, details) = match split {
Some((summary, details)) if !summary.is_empty() && !details.is_empty() => {
// Dedent the details separately so that people can have the summary on the
Expand Down

0 comments on commit 70990ec

Please sign in to comment.