citahub / cita_trie

Rust implementation of the Modified Patricia Tree (aka Trie).
Apache License 2.0
72 stars 28 forks source link

chore: use an explicit clone #21

Closed u2 closed 5 years ago

u2 commented 5 years ago

Use an explicit clone in ExtensionNode::new. Use an explicit clone in LeafNode::new, value.to_vec() is a implicit clone. Use an explicit clone in Nibbles::from_hex.

If in the function signature we use reference and inside the function body we clone the reference content, it's better we pass the real content in.

eg:

fn foo(a: &str) {
    a.clone()
    ...
}

fn bar(a: String) {
     foo(&a)
     foo(&a)
}

a better way is

fn foo(a: String) {
    a
    ...
}

fn bar(a: String) {
     foo(a.clone())
     foo(a)
}

There are two reasons:

  1. avoid some clone.
  2. explict function signature.
cryptowen commented 5 years ago

FYI, I am a little confused about memory management when pass a struct param to function and get struct return value. I did some search and this is a brief summary:

  1. All the function call is pass-by-value.
  2. The value which will be copied when passing is not always the whole data. For simple types, it is the value themselves; for vectors, it is the struct consist of pointer, cap and len; for pointers and references, it is a usize; for structures, it is the whole structure.
  3. For large values, the compiler may optimize away copies. For example, the following:
fn init_array() -> [u32; 256] {
    [!0; 256]
}

let array = init_array();

Will be optimized to something like this:

fn init_array(array: &mut [u32; 256]) {
    *array = [!0; 256];
}

let mut array = unsafe { mem::uninitialized() };
init_array(&mut array);

refs:

u2 commented 5 years ago

Rust is a Pass-by-value language, it always copies the value in the stack. For the copy type, the real value stores in the stack, for the clone there is a struct in the stack, the data part stores in the heap.