<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    On 10/02/2016 01:07 PM, Grzegorz Junka wrote:<br>
    <blockquote
      cite="mid:ae75c7d0-9583-2b4a-baf9-96c8b0f57a45@gjunka.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <p>I don't think Ruel was asking about differences between maps
        and records, only what datatype is optimal for map's keys?</p>
      <p>I was hoping someone from the OTP team will take on this
        question, but from what I understand the key is always hashed
        using some C functions. So, the shorter is the key the faster
        will be the hashing, but the difference will be so small, that
        only noticeable on really big data structures (like long
        lists/strings, binaries or deep data structures, like dicts,
        where it has to be traversed, and by long I mean a few dozens of
        bytes).</p>
    </blockquote>
    Maps were designed to handle all types as keys but it's best suited
    for literal keys, i.e. 'this_is_a_literal_key',
    "this_is_a_literal_key",
    <<"this_is_also_a_literal_key">>. It is true that
    comparisons are more expensive for larger keys, immediates (atoms
    and fixnums) are word comparisons, but for big maps this is not so
    problematic. The HAMT implementation only does one comparison on the
    key itself and that it is when it reaches the leaf, otherwise it
    uses the hash to traverses the hash value. Also, for literal keys
    the hashing is done at *load time* so it will only hash again when
    it that hash exhausted, typically this will happen if Maps are
    larger then 50000 pairs. For small maps there are more comparisons
    but the Map is small so who cares =)<br>
    <br>
    As for optimal keys .. it depends on your need. I would say atoms
    are optimal if you don't need to transcode the keys to atoms and
    back when you use them. Otherwise use the source type.<br>
    <br>
    // Björn-Egil<br>
    <br>
    <br>
    <blockquote
      cite="mid:ae75c7d0-9583-2b4a-baf9-96c8b0f57a45@gjunka.com"
      type="cite">
      <p>Grzegorz<br>
      </p>
      <br>
      <div class="moz-cite-prefix">On 01/10/2016 19:24, Jesper Louis
        Andersen wrote:<br>
      </div>
      <blockquote
cite="mid:CAGrdgiX0sGgEZiBAtYhbXHR-d_o-rW9_KYWj+ie5cv5YM_q5HA@mail.gmail.com"
        type="cite">
        <div dir="ltr">Hi,
          <div><br>
          </div>
          <div>You have to define optimal. Do you want efficient lookup
            or do you want to save space? For static keys, using atoms
            has the advantage of being fast to compare and rather small
            (1 machine word). For small maps, lookup speeds are so quick
            I don't think it really matters too much if a record is
            marginally faster. I'd go for readability over efficiency in
            almost all situations.</div>
          <div><br>
          </div>
          <div>As for the record vs maps discussion: I tend to use an
            algebraic datatype instead, so I can avoid representing
            state which is not valid. In some circumstances, a map is
            fit for the representation. One weakness of a record is that
            if we define</div>
          <div><br>
          </div>
          <div>-record(state, { name, socket }).</div>
          <div><br>
          </div>
          <div>then we need to have #state { socket = undefined } at
            some point if we don't have a valid socket. With a map, we
            can simply initialize to the state #{ name => Name } and
            then when the socket is opened later, we can do State#{
            socket => Sock } in the code and extend the state with a
            socket key. In a language such as OCaml, we could represent
            it as the type</div>
          <div><br>
          </div>
          <div>-type state() :: {unconnected, name()} | {connected,
            name(), socket()}.</div>
          <div><br>
          </div>
          <div>And I've done this in Erlang as well. It depends on the
            complexity of the representation. As for the goal: the goal
            is to build a state which is very hard to accidentally
            pattern match wrongly on in the code base. If your state has
            no socket, a match such as</div>
          <div><br>
          </div>
          <div>barney(#{ socket := Sock }) -> ...</div>
          <div><br>
          </div>
          <div>cannot match, even by accident. In turn, it forces the
            code to fail on the match itself, not later on when you try
            to do something with an undefined socket.</div>
          <div><br>
          </div>
        </div>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On Sat, Oct 1, 2016 at 12:37 PM,
            Pagayon, Ruel <span dir="ltr"><<a moz-do-not-send="true"
                href="mailto:ruel@ruel.me" target="_blank">ruel@ruel.me</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr">Hi everyone,
                <div><br>
                </div>
                <div>I'm just wondering (assuming the keys of my maps in
                  my application is not dynamically generated):</div>
                <div><br>
                </div>
                <div>1. What is the most optimal key type for maps?<br>
                </div>
                <div>2. If there is little to no effect in performance
                  (or resources in general), as a convention, which is
                  the best to use?</div>
                <div><br>
                </div>
                <div>Thank you in advance for your responses.</div>
                <div><br>
                </div>
                <div>Cheers,</div>
                <div>Ruel</div>
              </div>
              <br>
              ______________________________<wbr>_________________<br>
              erlang-questions mailing list<br>
              <a moz-do-not-send="true"
                href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
              <a moz-do-not-send="true"
                href="http://erlang.org/mailman/listinfo/erlang-questions"
                rel="noreferrer" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-questions</a><br>
              <br>
            </blockquote>
          </div>
          <br>
          <br clear="all">
          <div><br>
          </div>
          -- <br>
          <div class="gmail_signature" data-smartmail="gmail_signature">J.</div>
        </div>
        <br>
        <fieldset class="mimeAttachmentHeader"></fieldset>
        <br>
        <pre wrap="">_______________________________________________
erlang-questions mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
      </blockquote>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>