Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separate compilation for generics in Rust

Tags:

c++

generics

rust

C++ has been criticized because it lacks separate compilation of templates. C++ templates are compiled for (virtually) each instantiation. What is the state of the things for Rust concerning separate compilation of generics ? My understanding is that it behaves like C++ except that instantiations are cached during the compilation of each crate. Is that correct ?

like image 288
Gepp Avatar asked Sep 17 '14 15:09

Gepp


3 Answers

As far as I know, generics are stored in some serialized form in the crate where they are defined. When used in another crate (library or binary) they are instantiated from this serialized form. So they are monomorphized the same way as are C++ templates but the overhead of repeated parsing of unnecessary code is avoided.

like image 55
PEPP Avatar answered Nov 11 '22 16:11

PEPP


From the tutorial docs:

The Rust compiler compiles generic functions very efficiently by monomorphizing them. Monomorphization is a fancy name for a simple idea: generate a separate copy of each generic function at each call site, a copy that is specialized to the argument types and can thus be optimized specifically for them. In this respect, Rust's generics have similar performance characteristics to C++ templates. http://doc.rust-lang.org/0.11.0/tutorial.html#generics

EDIT: this didn't really answer your question, did it?

like image 24
AlexanderBrevig Avatar answered Nov 11 '22 18:11

AlexanderBrevig


Generic types and functions are monomorphized. However, it's possible to use traits without generics.

This is a generic function. It will be monomorphized.

fn get_length<T: Collection>(collection: &T) -> uint {
    collection.len()
}

This is an equivalent non-generic function. Only one copy of this function will be included in the binary.

fn get_length(collection: &Collection) -> uint {
    collection.len()
}

Note that we couldn't make a function that receives a Collection by value, because Collection is a trait, and thus it has no specific size. A generic function is required in this case.

There are some things you can't do with generics and some things you can't do with trait references. With trait references, you need a trait, obviously. With generics, you can't have a vector of collections where the collections are of different types (e.g. you couldn't put a Vec<int> and a String in that vector), but you can with trait references: a Vec<&Collection> can contain a &Vec<int> and a &String.

like image 1
Francis Gagné Avatar answered Nov 11 '22 18:11

Francis Gagné