title: Most memory-efficient and fastest way to create a HashMap based on vector elements
body: <p>Let's say we read millions of items (from a DB table, JSON file, etc.) into <code>Vec&lt;Item&gt;</code>:</p>
  <pre><code>#[derive(Clone)]
  struct Item {
      id: u64,
      name: String,
      //...
  }
  let items: Vec&lt;Item&gt; = load_items();
  </code></pre>
  <p>Very often, in order to process that data efficiently, we would need additional data structures, such as a HashMap with one of item's fields as a key and the item itself as a value. The simplest way to do that, in my view, is something like this:</p>
  <pre><code>let map_by_name: HashMap&lt;String, Item&gt; = items.iter().map(|x| (x.name.clone(), x.clone())).collect();
  </code></pre>
  <p>That's simple and easy. But here we <strong>clone</strong> all the data, which obviously isn't optimal in terms of performance and memory usage.</p>
  <p>In GC-based languages (Java, .NET, Python, JS, etc.) this particular problem doesn't exist - the simplest and most natural implementation wouldn't involve cloning but only storing additional references to the objects in the vector.</p>
  <p>In Rust, AFAIK, we cannot move or reference vector elements. So what would be the most efficient alternative then? The following ideas come to mind:</p>
  <ol>
  <li>Using <a href="https://doc.rust-lang.org/std/rc/struct.Rc.html" rel="nofollow noreferrer"><code>Rc</code></a>:</li>
  </ol>
  <pre><code>let items: Vec&lt;Rc&lt;Item&gt;&gt; = load_items();
  let map_by_name: HashMap&lt;String, Rc&lt;Item&gt;&gt; = items.iter().map(|x| (x.name.clone(), Rc::clone(&amp;x))).collect();
  </code></pre>
  <ol start="2">
  <li>In the HashMap value we only store the element's index in the vector:</li>
  </ol>
  <pre><code>let map_by_name: HashMap&lt;String, usize&gt; = items.iter().enumerate().map(|(i, x)| (x.name.clone(), i)).collect();
  </code></pre>
  <p>Is my understanding correct, that the second approach should be generally more efficient than the first, but it could be less convenient if we needed to pass the map to other functions, as it would always require us to pass the vector as well?</p>
  <p>Also, is there a third approach that I am missing?</p>
  <p>P.S.: In the examples above I used a cloned <code>String</code> as a key. It's clear we might also use <code>&amp;str</code> obtained via <code>x.name.as_ref()</code> if that makes sense for a particular situation, but I wanted to particularly focus on the bigger problem - the items themselves.</p>