Skip to content

Commit eb6edab

Browse files
authored
Merge pull request RustPython#2397 from RustPython/coolreader18/fasthash
Use ahash instead of siphash in a few places
2 parents d2abad5 + 8cdef9e commit eb6edab

25 files changed

+274
-142
lines changed

Cargo.lock

Lines changed: 159 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bytecode/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "MIT"
1111
[dependencies]
1212
bincode = "1.1"
1313
bitflags = "1.1"
14-
lz4_flex = "0.5"
14+
lz4_flex = "0.7"
1515
num-bigint = { version = "0.3", features = ["serde"] }
1616
num-complex = { version = "0.3", features = ["serde"] }
1717
serde = { version = "1.0", features = ["derive"] }

compiler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rustpython-ast = { path = "../ast" }
1515
num-complex = { version = "0.3", features = ["serde"] }
1616
num-traits = "0.2"
1717
log = "0.4"
18-
arrayvec = "0.5"
18+
ahash = "0.6"
1919

2020
[dev-dependencies]
2121
rustpython-parser = { path = "../parser" }

compiler/src/compile.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::error::{CompileError, CompileErrorType};
99
use crate::ir::{self, CodeInfo};
1010
pub use crate::mode::Mode;
1111
use crate::symboltable::{make_symbol_table, statements_to_symbol_table, SymbolScope, SymbolTable};
12-
use indexmap::IndexSet;
12+
use crate::IndexSet;
1313
use itertools::Itertools;
1414
use num_complex::Complex64;
1515
use num_traits::ToPrimitive;
@@ -140,10 +140,10 @@ impl Compiler {
140140
blocks: vec![ir::Block::default()],
141141
current_block: bytecode::Label(0),
142142
constants: Vec::new(),
143-
name_cache: IndexSet::new(),
144-
varname_cache: IndexSet::new(),
145-
cellvar_cache: IndexSet::new(),
146-
freevar_cache: IndexSet::new(),
143+
name_cache: IndexSet::default(),
144+
varname_cache: IndexSet::default(),
145+
cellvar_cache: IndexSet::default(),
146+
freevar_cache: IndexSet::default(),
147147
};
148148
Compiler {
149149
code_stack: vec![module_code],
@@ -217,8 +217,8 @@ impl Compiler {
217217
blocks: vec![ir::Block::default()],
218218
current_block: bytecode::Label(0),
219219
constants: Vec::new(),
220-
name_cache: IndexSet::new(),
221-
varname_cache: IndexSet::new(),
220+
name_cache: IndexSet::default(),
221+
varname_cache: IndexSet::default(),
222222
cellvar_cache,
223223
freevar_cache,
224224
};

compiler/src/ir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use indexmap::IndexSet;
1+
use crate::IndexSet;
22
use rustpython_bytecode::{CodeFlags, CodeObject, ConstantData, Instruction, Label, Location};
33

44
pub type BlockIdx = Label;

compiler/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#[macro_use]
66
extern crate log;
77

8+
type IndexMap<K, V> = indexmap::IndexMap<K, V, ahash::RandomState>;
9+
type IndexSet<T> = indexmap::IndexSet<T, ahash::RandomState>;
10+
811
pub mod compile;
912
pub mod error;
1013
pub mod ir;

compiler/src/symboltable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Inspirational file: https://github.com/python/cpython/blob/master/Python/symtabl
88
*/
99

1010
use crate::error::{CompileError, CompileErrorType};
11-
use indexmap::map::IndexMap;
11+
use crate::IndexMap;
1212
use rustpython_ast::{self as ast, Location};
1313
use std::fmt;
1414

@@ -58,7 +58,7 @@ impl SymbolTable {
5858
typ,
5959
line_number,
6060
is_nested,
61-
symbols: IndexMap::new(),
61+
symbols: IndexMap::default(),
6262
sub_tables: vec![],
6363
}
6464
}

parser/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ num-traits = "0.2"
2020
unic-emoji-char = "0.9"
2121
unic-ucd-ident = "0.9"
2222
unicode_names2 = "0.4"
23+
phf = { version = "0.8", features = ["macros"] }
24+
hashbrown = "0.9"
25+
ahash = "0.6"

parser/src/function.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ahash::RandomState;
12
use std::collections::HashSet;
23

34
use crate::ast;
@@ -45,7 +46,7 @@ pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ast::ArgumentList,
4546
let mut args = vec![];
4647
let mut keywords = vec![];
4748

48-
let mut keyword_names = HashSet::with_capacity(func_args.len());
49+
let mut keyword_names = HashSet::with_capacity_and_hasher(func_args.len(), RandomState::new());
4950
for (name, value) in func_args {
5051
match name {
5152
Some(n) => {

parser/src/lexer.rs

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use num_traits::identities::Zero;
1010
use num_traits::Num;
1111
use std::char;
1212
use std::cmp::Ordering;
13-
use std::collections::HashMap;
1413
use std::str::FromStr;
1514
use unic_emoji_char::is_emoji_presentation;
1615
use unic_ucd_ident::{is_xid_continue, is_xid_start};
@@ -66,52 +65,48 @@ pub struct Lexer<T: Iterator<Item = char>> {
6665
chr1: Option<char>,
6766
chr2: Option<char>,
6867
location: Location,
69-
keywords: HashMap<String, Tok>,
7068
}
7169

72-
pub fn get_keywords() -> HashMap<String, Tok> {
73-
let mut keywords: HashMap<String, Tok> = HashMap::new();
74-
70+
pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! {
7571
// Alphabetical keywords:
76-
keywords.insert(String::from("..."), Tok::Ellipsis);
77-
keywords.insert(String::from("False"), Tok::False);
78-
keywords.insert(String::from("None"), Tok::None);
79-
keywords.insert(String::from("True"), Tok::True);
80-
81-
keywords.insert(String::from("and"), Tok::And);
82-
keywords.insert(String::from("as"), Tok::As);
83-
keywords.insert(String::from("assert"), Tok::Assert);
84-
keywords.insert(String::from("async"), Tok::Async);
85-
keywords.insert(String::from("await"), Tok::Await);
86-
keywords.insert(String::from("break"), Tok::Break);
87-
keywords.insert(String::from("class"), Tok::Class);
88-
keywords.insert(String::from("continue"), Tok::Continue);
89-
keywords.insert(String::from("def"), Tok::Def);
90-
keywords.insert(String::from("del"), Tok::Del);
91-
keywords.insert(String::from("elif"), Tok::Elif);
92-
keywords.insert(String::from("else"), Tok::Else);
93-
keywords.insert(String::from("except"), Tok::Except);
94-
keywords.insert(String::from("finally"), Tok::Finally);
95-
keywords.insert(String::from("for"), Tok::For);
96-
keywords.insert(String::from("from"), Tok::From);
97-
keywords.insert(String::from("global"), Tok::Global);
98-
keywords.insert(String::from("if"), Tok::If);
99-
keywords.insert(String::from("import"), Tok::Import);
100-
keywords.insert(String::from("in"), Tok::In);
101-
keywords.insert(String::from("is"), Tok::Is);
102-
keywords.insert(String::from("lambda"), Tok::Lambda);
103-
keywords.insert(String::from("nonlocal"), Tok::Nonlocal);
104-
keywords.insert(String::from("not"), Tok::Not);
105-
keywords.insert(String::from("or"), Tok::Or);
106-
keywords.insert(String::from("pass"), Tok::Pass);
107-
keywords.insert(String::from("raise"), Tok::Raise);
108-
keywords.insert(String::from("return"), Tok::Return);
109-
keywords.insert(String::from("try"), Tok::Try);
110-
keywords.insert(String::from("while"), Tok::While);
111-
keywords.insert(String::from("with"), Tok::With);
112-
keywords.insert(String::from("yield"), Tok::Yield);
113-
keywords
114-
}
72+
"..." => Tok::Ellipsis,
73+
"False" => Tok::False,
74+
"None" => Tok::None,
75+
"True" => Tok::True,
76+
77+
"and" => Tok::And,
78+
"as" => Tok::As,
79+
"assert" => Tok::Assert,
80+
"async" => Tok::Async,
81+
"await" => Tok::Await,
82+
"break" => Tok::Break,
83+
"class" => Tok::Class,
84+
"continue" => Tok::Continue,
85+
"def" => Tok::Def,
86+
"del" => Tok::Del,
87+
"elif" => Tok::Elif,
88+
"else" => Tok::Else,
89+
"except" => Tok::Except,
90+
"finally" => Tok::Finally,
91+
"for" => Tok::For,
92+
"from" => Tok::From,
93+
"global" => Tok::Global,
94+
"if" => Tok::If,
95+
"import" => Tok::Import,
96+
"in" => Tok::In,
97+
"is" => Tok::Is,
98+
"lambda" => Tok::Lambda,
99+
"nonlocal" => Tok::Nonlocal,
100+
"not" => Tok::Not,
101+
"or" => Tok::Or,
102+
"pass" => Tok::Pass,
103+
"raise" => Tok::Raise,
104+
"return" => Tok::Return,
105+
"try" => Tok::Try,
106+
"while" => Tok::While,
107+
"with" => Tok::With,
108+
"yield" => Tok::Yield,
109+
};
115110

116111
pub type Spanned = (Location, Tok, Location);
117112
pub type LexResult = Result<Spanned, LexicalError>;
@@ -193,7 +188,6 @@ where
193188
location: Location::new(0, 0),
194189
chr1: None,
195190
chr2: None,
196-
keywords: get_keywords(),
197191
};
198192
lxr.next_char();
199193
lxr.next_char();
@@ -245,8 +239,8 @@ where
245239
}
246240
let end_pos = self.get_pos();
247241

248-
if self.keywords.contains_key(&name) {
249-
Ok((start_pos, self.keywords[&name].clone(), end_pos))
242+
if let Some(tok) = KEYWORDS.get(name.as_str()) {
243+
Ok((start_pos, tok.clone(), end_pos))
250244
} else {
251245
Ok((start_pos, Tok::Name { name }, end_pos))
252246
}

0 commit comments

Comments
 (0)