Skip to content

Commit

Permalink
perf: Allocate all temporaries into the same Vec
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Mar 15, 2020
1 parent a44e312 commit af945c4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 35 deletions.
49 changes: 22 additions & 27 deletions parser/src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{ReplLine, Variant, new_ident};
use crate::token::{Token, StringLiteral};
use crate::ordered_float::NotNan;

use crate::{Error, ErrorEnv, FieldExpr, FieldPattern, MutIdentEnv, TempVecs, Slice};
use crate::{Error, ErrorEnv, FieldExpr, FieldPattern, MutIdentEnv, TempVecs, TempVecStart, Slice};

grammar<'input, 'env, 'ast, Id>(
input: &'input dyn crate::ParserSource,
Expand Down Expand Up @@ -102,11 +102,8 @@ Comma<Rule>: Vec<Rule> = {

#[inline]
SepSlice<Rule, Separator>: &'ast mut Slice<Rule> =
<mut rules: ManyVec<(<Rule> Separator)>> <last: Rule?> => {
rules.extend(last);
let slice = arena.alloc_extend(rules.drain(..));
temp_vecs.push(rules);
slice
<start: ManyVec<(<Rule> Separator)>> <last: Rule?> => {
arena.alloc_extend(temp_vecs.drain(start).chain(last))
};

#[inline]
Expand All @@ -123,21 +120,21 @@ IdentStr: &'input str = {
"(" <"operator"> ")" => <>,
};

Many1Vec<T>: Vec<T> = {
Many1Vec<T>: TempVecStart<T> = {
T => {
let mut v = temp_vecs.pop();
v.push(<>);
v
let start = temp_vecs.start();
temp_vecs.select().push(<>);
start
},
<mut xs: Many1Vec<T>> <x: T> => {
xs.push(x);
xs
<start: Many1Vec<T>> <x: T> => {
temp_vecs.select().push(x);
start
}
};

#[inline]
ManyVec<T>: Vec<T> = {
=> Vec::new(),
ManyVec<T>: TempVecStart<T> = {
=> temp_vecs.start(),
Many1Vec<T>,
};

Expand All @@ -150,10 +147,8 @@ Many<T>: &'ast mut Slice<T> = {
#[inline]
Many1<T>: &'ast mut Slice<T> = {
Many1Vec<T> => {
let mut xs = <>;
let slice = arena.alloc_extend(xs.drain(..));
temp_vecs.push(xs);
slice
let start = <>;
arena.alloc_extend(temp_vecs.drain(start))
}
};

Expand Down Expand Up @@ -552,9 +547,9 @@ AtomicPattern: Pattern<'ast, Id> = {
}
}

let mut types = temp_vecs.pop();
let mut types = mem::take(temp_vecs.select());
types.reserve(types_len);
let mut values = temp_vecs.pop();
let mut values = mem::take(temp_vecs.select());
values.reserve(values_len);

for field in fields {
Expand All @@ -580,8 +575,8 @@ AtomicPattern: Pattern<'ast, Id> = {
.value
.map(|_| pos::spanned(implicit_import_span, env.from_str(&format!("implicit?{}", implicit_import_span.start())))),
};
temp_vecs.push(types);
temp_vecs.push(values);
*temp_vecs.select() = types;
*temp_vecs.select() = values;
pattern
},
};
Expand Down Expand Up @@ -767,9 +762,9 @@ AtomicExpr: Expr<'ast, Id> = {
}
}

let mut types = temp_vecs.pop();
let mut types = mem::take(temp_vecs.select());
types.reserve(types_len);
let mut values = temp_vecs.pop();
let mut values = mem::take(temp_vecs.select());
values.reserve(values_len);

for field in fields {
Expand All @@ -793,8 +788,8 @@ AtomicExpr: Expr<'ast, Id> = {
exprs: arena.alloc_extend(values.drain(..)),
base: base.map(|e| arena.alloc(e)),
};
temp_vecs.push(types);
temp_vecs.push(values);
*temp_vecs.select() = types;
*temp_vecs.select() = values;
expr
},
};
Expand Down
26 changes: 18 additions & 8 deletions parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern crate quick_error;
#[macro_use]
extern crate pretty_assertions;

use std::{fmt, hash::Hash, sync::Arc};
use std::{fmt, hash::Hash, marker::PhantomData, sync::Arc};

use crate::base::{
ast::{
Expand Down Expand Up @@ -253,18 +253,21 @@ type ErrorEnv<'err, 'input> = &'err mut Errors<LalrpopError<'input>>;
type Slice<T> = [T];

trait TempVec<'ast, Id>: Sized {
fn select<'a>(vecs: &'a mut TempVecs<'ast, Id>) -> &'a mut Vec<Vec<Self>>;
fn select<'a>(vecs: &'a mut TempVecs<'ast, Id>) -> &'a mut Vec<Self>;
}

macro_rules! impl_temp_vec {
($( $ty: ty => $field: ident),* $(,)?) => {
#[doc(hidden)]
pub struct TempVecs<'ast, Id> {
$(
$field: Vec<Vec<$ty>>,
$field: Vec<$ty>,
)*
}

#[doc(hidden)]
pub struct TempVecStart<T>(usize, PhantomData<T>);

impl<'ast, Id> TempVecs<'ast, Id> {
fn new() -> Self {
TempVecs {
Expand All @@ -274,24 +277,31 @@ macro_rules! impl_temp_vec {
}
}

fn push<T>(&mut self, exprs: Vec<T>)
fn start<T>(&mut self) -> TempVecStart<T>
where
T: TempVec<'ast, Id>,
{
T::select(self).push(exprs);
TempVecStart(T::select(self).len(), PhantomData)
}

fn pop<T>(&mut self) -> Vec<T>
fn select<T>(&mut self) -> &mut Vec<T>
where
T: TempVec<'ast, Id>,
{
T::select(self).pop().unwrap_or_default()
T::select(self)
}

fn drain<'a, T>(&'a mut self, start: TempVecStart<T>) -> impl Iterator<Item = T> + 'a
where
T: TempVec<'ast, Id> + 'a,
{
T::select(self).drain(start.0..)
}
}

$(
impl<'ast, Id> TempVec<'ast, Id> for $ty {
fn select<'a>(vecs: &'a mut TempVecs<'ast, Id>) -> &'a mut Vec<Vec<Self>> {
fn select<'a>(vecs: &'a mut TempVecs<'ast, Id>) -> &'a mut Vec<Self> {
&mut vecs.$field
}
}
Expand Down

0 comments on commit af945c4

Please sign in to comment.