Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should simple enums derive Copy? Is there any difference in performance?

Tags:

rust

use std::collections::HashMap;

// #[derive(Copy, Clone)]
enum SomeEnum {
    Some1,
    Some2,
}

struct SomeStruct {
    pub some_enum: SomeEnum,
    pub s: String,
}

fn proc_struct(some_struct: &SomeStruct) {
    let mut map = HashMap::new();
    map.insert(String::from("any"), 0);

    match map.get(&some_struct.s) { // just to make a reference in SomeStruct
        Some(v) => {
            proc1(some_struct.some_enum);
            proc2(&some_struct.some_enum);
        }
        None => {}
    }
}

fn proc1(some: SomeEnum) {}

fn proc2(some: &SomeEnum) {}

fn main() {
    let some_struct = SomeStruct { some_enum: SomeEnum::Some1, s: String::from("s") };

    proc_struct(&some_struct);
}

The above code produces the following error:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:20:19
   |
20 |             proc1(some_struct.some_enum);
   |                   ^^^^^^^^^^^ cannot move out of borrowed content

When I add #[derive(Copy, Clone)] to SomeEnum, it compiles fine.

Should simple enums like SomeEnum derive the Copy trait? Is there any difference in performance between functions proc1() and proc2()?

like image 474
sbant Avatar asked Jun 22 '17 09:06

sbant


1 Answers

Citing the docs:

Generally speaking, if your type can implement Copy, it should.

Since your SomeEnum has no composite variants (e.g. Vecs or Strings), I recommend making it Copyable. It appears that it is actually smaller than a reference to it:

use std::mem;

enum SomeEnum {
    Some1,
    Some2,
}

fn main() {
    assert_eq!(1, mem::size_of::<SomeEnum>());
    assert_eq!(8, mem::size_of::<&SomeEnum>());
}

Though I doubt that in this case you will be able to detect any difference in performance.

like image 77
ljedrz Avatar answered Oct 16 '22 21:10

ljedrz