Skip to content

Commit

Permalink
perf: Use SmallVec for the Type::Variants constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Aug 25, 2016
1 parent e925925 commit de33d9a
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 12 deletions.
19 changes: 12 additions & 7 deletions base/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub fn instantiate<F>(typ: TcType, mut f: F) -> TcType
/// the number of elements in the `SmallVec` so that it fills out the entire `Type` enum while not
/// increasing the size of `Type`.
pub type AppVec<T> = SmallVec<[T; 2]>;
pub type VariantVec<T> = SmallVec<[T; 3]>;

/// The representation of gluon's types.
///
Expand All @@ -102,7 +103,7 @@ pub enum Type<Id, T = AstType<Id>> {
/// A variant type `| A Int Float | B`.
/// The second element of the tuple is the function type which the constructor has which in the
/// above example means that A's type is `Int -> Float -> A` and B's is `B`
Variants(Vec<(Id, T)>),
Variants(VariantVec<(Id, T)>),
/// Representation for type variables
Variable(TypeVariable),
/// Variant for "generic" variables. These occur in signatures as lowercase identifers `a`, `b`
Expand Down Expand Up @@ -448,8 +449,10 @@ impl<Id, T> Type<Id, T>
}
}

pub fn variants(vs: Vec<(Id, T)>) -> T {
T::from(Type::Variants(vs))
pub fn variants<I>(vs: I) -> T
where I: IntoIterator<Item = (Id, T)>
{
T::from(Type::Variants(vs.into_iter().collect()))
}

pub fn record(types: Vec<Field<Id, Alias<Id, T>>>, fields: Vec<Field<Id, T>>) -> T {
Expand Down Expand Up @@ -1053,7 +1056,9 @@ pub fn walk_move_type_opt<F: ?Sized, I, T>(typ: &Type<I, T>, f: &mut F) -> Optio
new_fields.map(|fields| Type::record(types.clone(), fields))
}
Type::Variants(ref variants) => {
walk_move_types(Vec::new(), variants, |v| f.visit(&v.1).map(|t| (v.0.clone(), t)))
walk_move_types(VariantVec::new(),
variants,
|v| f.visit(&v.1).map(|t| (v.0.clone(), t)))
.map(Type::variants)
}
Type::Hole |
Expand All @@ -1066,11 +1071,11 @@ pub fn walk_move_type_opt<F: ?Sized, I, T>(typ: &Type<I, T>, f: &mut F) -> Optio
}

// FIXME Add R: Default and remove the `out` parameter
pub fn walk_move_types<'a, I, F, T, R>(mut out: R, types: I, mut f: F) -> Option<R>
pub fn walk_move_types<'a, I, F, T, R>(mut out: R, types: I, mut f: F) -> Option<R>
where I: IntoIterator<Item = &'a T>,
F: FnMut(&'a T) -> Option<T>,
T: Clone + 'a,
R: VecLike<T>,
R: VecLike<T>
{
walk_move_types2(types.into_iter(), false, &mut out, &mut f);
if out.len() == 0 {
Expand All @@ -1084,7 +1089,7 @@ fn walk_move_types2<'a, I, F, T, R>(mut types: I, replaced: bool, output: &mut R
where I: Iterator<Item = &'a T>,
F: FnMut(&'a T) -> Option<T>,
T: Clone + 'a,
R: VecLike<T>,
R: VecLike<T>
{
if let Some(typ) = types.next() {
let new = f(typ);
Expand Down
4 changes: 2 additions & 2 deletions check/src/kindcheck.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;

use base::ast;
use base::types::{self, BuiltinType, Generic, RcKind, TcType, Type, Kind, merge};
use base::types::{self, BuiltinType, Generic, RcKind, TcType, Type, Kind, VariantVec, merge};
use base::symbol::Symbol;
use base::types::{KindEnv, Walker};

Expand Down Expand Up @@ -181,7 +181,7 @@ impl<'a> KindCheck<'a> {
Ok((kind, Type::app(ctor, new_args)))
}
Type::Variants(ref variants) => {
let variants = try!(variants.iter()
let variants: VariantVec<_> = try!(variants.iter()
.map(|variant| {
let (kind, typ) = try!(self.kindcheck(&variant.1));
let type_kind = self.type_kind();
Expand Down
3 changes: 1 addition & 2 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,8 +1209,7 @@ impl<'a> Typecheck<'a> {
Some(new) => (new.clone(), old.1.clone()),
None => old.clone(),
}
})
.collect()))
})))
} else {
None
}
Expand Down
2 changes: 1 addition & 1 deletion parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl<'input, I, Id, F> ParserEnv<I, F>
many(self.parser(ParserEnv::<I, F>::type_arg)))
.map(|(_, id, args): (_, _, Vec<_>)| (id, Type::function(args, return_type.clone())));
many1(variant)
.map(Type::variants)
.map(|v: Vec<_>| Type::variants(v))
.parse_state(input)
}

Expand Down

0 comments on commit de33d9a

Please sign in to comment.