如何避免多次重新实例化正则表达式?

问题描述 投票:0回答:1

我已经用 Rust 编写了代码 2023 第一天的解决方案,并使其正常工作。大致结构是这样的:

fn parse_number(line: &str) -> Option<i32> {
  Regex::new(...).unwrap()...
}

fn parse_line(line: &str) -> (i32, i32) {
  let first_parsed = parse_number(&line).unwrap();
  let last_parsed = parse_number(&line).unwrap_or(first_parsed);
  (first_parsed, last_parsed)
}

fn day_1(path: &str) -> i32 {
  let file = fs::read_to_string(path).expect("ok");
  file
    .lines()
    .fold(0, |acc, line| {
      ...parse_line(...)...
    })
}

现在我认为可能的性能优化是避免一遍又一遍地重新初始化相同的正则表达式,所以我想做这样的事情:

fn parse_number(re: Regex, line: &str) -> Option<i32> {
  re...
}

fn parse_line(first_regex: Regex, second_regex: Regex, line: &str) -> (i32, i32) {
  let first_parsed = parse_number(first_regex, &line).unwrap();
  let last_parsed = parse_number(second_regex, &line).unwrap_or(first_parsed);
  (first_parsed, last_parsed)
}

fn day_1(path: &str) -> i32 {
  let first_regex = Regex::new(...).unwrap();
  let second_regex = Regex::new(...).unwrap();
  let file = fs::read_to_string(path).expect("ok");
  file
    .lines()
    .fold(0, |acc, line| {
      ...parse_line(&first_regex, &second_regex, &line)...
    })
}

问题是借用检查器抱怨我正在移动正则表达式对象(显然我就是这样),但是处理这个问题的常见模式是什么?我希望能够对所有操作重用前两个正则表达式对象,但第二个优先事项是克隆它们,我认为这仍然比我现在所做的更快。

rust borrow-checker
1个回答
2
投票

Regex
上的方法将对 self 的引用作为接收者(
&self
,而不是
self
),因此您可以将拥有的值交换为对它的引用:

use regex::Regex;
fn parse_number(re: &Regex, line: &str) -> Option<i32> {
    todo!()
}

当你可以逃脱惩罚时,使用参考文献而不是拥有的东西通常是一个好主意。

由于正则表达式更多的是

parse_line
函数的属性,因此我会使用延迟初始化的
static
来代替,就像 tadman 和 Masklinn 建议的那样:

use std::sync::OnceLock;
fn parse_line(line: &str) -> (i32, i32) {
    static RE: OnceLock<(Regex, Regex)> = OnceLock::new();
    let (first_regex, last_regex) = RE.get_or_init(|| (Regex::new("").unwrap(), Regex::new("").unwrap()));

    let first_parsed = parse_number(first_regex, &line).unwrap();
    let last_parsed = parse_number(last_regex, &line).unwrap_or(first_parsed);
    (first_parsed, last_parsed)
}
© www.soinside.com 2019 - 2024. All rights reserved.