<div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Date: Wed, 8 Oct 2008 17:01:25 +0100<br>
From: Joel Reymont <<a href="mailto:joelr1@gmail.com">joelr1@gmail.com</a>><br>
Subject: [erlang-questions] pid to integer and back<br>
To: Erlang Questions <<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>><br>
Message-ID: <<a href="mailto:FF73DCB8-F9F4-4B2F-932B-CACAD0F34381@gmail.com">FF73DCB8-F9F4-4B2F-932B-CACAD0F34381@gmail.com</a>><br>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes<br>
<br>
Is there a safe and efficient way to convert pid to integer and back?<br>
<br>
I'm assigning each running poker game an integer id. I store this id<br>
into every outgoing packet so there's no database lookup.<br>
<br>
I use the id to lookup the game process for every incoming packet,<br>
though. This is proving to be extremely inefficient, even with dirty<br>
mnesia reads.<br>
<br>
I actually repeat the above for every player, so there's twice the<br>
overhead. Is there a way to avoid it?<br>
<br>
This would only apply to running games and connected players so this<br>
would be a temporary integer, valid while the process is alive.</blockquote><div> </div></div>There are three general approaches to this.<br><br><br><br>1) You can pack any known integer ranges into another integer through radix multiplication.  You know, for example, that you can store four decks of cards { redback, 6, hearts } in an octet by skipping ranges up to fill:<br>
<br>-define(Suits, [hearts,clubs,spades,diamonds]).<br>
-define(Faces, [ace,2,3,4,5,6,7,8,9,10,jack,queen,king]).<br>
-define(Backs, [red,blue,green,black]).<br>
<br>function get_card_id( { ThisBack, ThisFace, ThisSuit } ) -><br>    SuitRadix = length(?Suits),<br>    FaceRadix = length(?Faces),<br>    ThisSuit + (ThisFace * SuitRadix) + (ThisBack * (SuitRadix*FaceRadix)).<br><br>
So, if you can find documentation of the maximum range of the three integers in a PID, you can just compose them this way.<br><br><br><br>2) You can keep a lookup process somewhere, and just dole out integer handles.<br><br>
3) You can notice that local PIDs already only eat one word, and quit playing translation games, because they're unnecessary.  (reference: <a href="http://www.erlang.org/doc/efficiency_guide/advanced.html">http://www.erlang.org/doc/efficiency_guide/advanced.html</a> )<br>
<br><br><br>The real question you should be asking yourself, in my opinion, is why you're that worried about a few bytes, and why you're trying to represent it as an integer in the first place.  In most cases where people say "I need to reduce their size because there are so many they're getting out of control", it's quite common to be able to reduce the count of IDs, rather than the size of their representation.<br>
<br>For example, if each of your player processes has a handle to each other player process, spin up a process for a given match instead, and give the player processes a hook to that and nothing else.  Bang: 7/8 or so savings on PID space, and probably a significant speed increase despite the extra messaging, since you're going to get so many more correct branch predictions and cache wins.  Granted, you probably aren't making a mistake that basic, and I haven't actually looked at your code, but it's an example that's clear enough to get me out of extra explanation.<br>
<br>Micro-optimization is almost never the right way to push back machine limits.  Consider working on your approach instead.<br>
</div>