检查给定单词是否存在于固定单词列表中的最快方法

时间:2018-10-15 17:38:35

标签: dictionary rust

这可能不是特定于Rust的,尽管这是我目前关注的语言。

我正在编写一个函数来将语言(MySQL)解析为令牌,并以格式化的方式输出它们,其中一部分包括查找当前工作令牌以查看它是名称,函数还是列/表名。

当前,我正在使用匹配语句

pub fn is_word(word: &str) -> bool {
    match word {
        "accessible"
        | "account"
        | "action"
        | "active"
        | "add"
        // ...
        | "year"
        | "year_month"
        | "zerofill" => true,
        _ => false,
    }
}

actual list长得多。

这是解决此问题的最佳方法吗?我已经尝试过将HashMap.contains_key()一起使用,但是速度明显较慢


我的HashMap implementation看起来像这样:

use std::collections::HashMap;

lazy_static! {
    static ref words: HashMap<&'static str, u8> = hashmap!{
        "accessible" => 0,
        "account" => 0,
        "action" => 0,
        "active" => 0,
        "add" => 0,
        // ...
        "year" => 0,
        "year_month" => 0,
        "zerofill" => 0,
    };
}

pub fn is_word(word: &str) -> bool {
    words.contains_key(word)
}

1 个答案:

答案 0 :(得分:5)

由于列表是在编译时固定的,因此请使用perfect hash提供的phf crate

build.rs

extern crate phf_codegen;

use std::env;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;

fn main() {
    let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs");
    let mut file = BufWriter::new(File::create(&path).unwrap());

    write!(&mut file, "static KEYWORDS: phf::Set<&'static str> = ").unwrap();
    phf_codegen::Set::new()
        .entry("accessible")
        .entry("account")
        .entry("action")
        .entry("active")
        .entry("add")
        // ...
        .entry("year")
        .entry("year_month")
        .entry("zerofill")
        .build(&mut file)
        .unwrap();
    write!(&mut file, ";\n").unwrap();
}

src / main.rs

extern crate phf;

include!(concat!(env!("OUT_DIR"), "/codegen.rs"));

pub fn is_word(word: &str) -> bool {
    KEYWORDS.contains(word)
}

根据您提供的基准测试代码,这至少与之前一样快。