Enum and inheritance


#1

I’m struggling with a optimization problem. I have to represent a set of objects and they share common behaviour. Rust teaches: use an enum and define some methods, for example:

enum Object {
    Variant1 {
        field: ... // for example u64
    },
    Variant2 {
        field1: Option<Box<Object>>
        ...
        fieldN: Option<Box<Object>>
    },
    ...
    VariantM {
        field1: Option<Box<Object>>
        ...
        fieldN: Option<Box<Object>>
    }
}

impl Object {
    // methods
}

Now, the size of Object is the same of biggest variant: there are variants with 8/16 bytes of size and other with 80/120 bytes. Some variantas are big because the type of some fields is Box<Object>. So the enum solution is not efficient as C++ inheritance.
In the future I will want allocate by hand the objects (with a custom memory manager) and I will track dead objects with some garbage collector algorithm. For example I could use a buddy system for allocating and a simple mark&sweep for garbage collection. So I need to handle a memory area where put instances of my objects (I don’t need Rust custom allocators!)

What can I do?


#2

One solutions is to implement the basic version first, and benchmark the CPU and memory resources it uses. If they are excessive you can try to replace some fields with box<>, that is allocate them elsewhere (this is what Rustc does in some cases). There are also crates for memory arenas.


#3

Box’s size would be just the size of a pointer, or two pointers if you have a trait object (which it doesn’t sound like you have). So Box itself doesn’t make your variants any bigger than if you were storing a usize.

In fact, as @leonardo mentioned, you can make the large variants smaller by putting their data on the heap via a Box.

Enum with or without Box? has a bit more discussion on enum layout decisions.


#4

Can’t you just skip the enum part and use traits?


#5

I fixed my post because it skipped some characters!