这可能不是特定于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)
}
答案 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)
}
根据您提供的基准测试代码,这至少与之前一样快。