[erlang-questions] erlang-questions Digest, Vol 17, Issue 41

John Haugeland stonecypher@REDACTED
Thu Oct 9 20:31:07 CEST 2008

> Date: Wed, 8 Oct 2008 17:01:25 +0100
> From: Joel Reymont <joelr1@REDACTED>
> Subject: [erlang-questions] pid to integer and back
> To: Erlang Questions <erlang-questions@REDACTED>
> Message-ID: <FF73DCB8-F9F4-4B2F-932B-CACAD0F34381@REDACTED>
> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
> Is there a safe and efficient way to convert pid to integer and back?
> I'm assigning each running poker game an integer id. I store this id
> into every outgoing packet so there's no database lookup.
> I use the id to lookup the game process for every incoming packet,
> though. This is proving to be extremely inefficient, even with dirty
> mnesia reads.
> I actually repeat the above for every player, so there's twice the
> overhead. Is there a way to avoid it?
> This would only apply to running games and connected players so this
> would be a temporary integer, valid while the process is alive.

There are three general approaches to this.

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:

-define(Suits, [hearts,clubs,spades,diamonds]).
-define(Faces, [ace,2,3,4,5,6,7,8,9,10,jack,queen,king]).
-define(Backs, [red,blue,green,black]).

function get_card_id( { ThisBack, ThisFace, ThisSuit } ) ->
    SuitRadix = length(?Suits),
    FaceRadix = length(?Faces),
    ThisSuit + (ThisFace * SuitRadix) + (ThisBack * (SuitRadix*FaceRadix)).

So, if you can find documentation of the maximum range of the three integers
in a PID, you can just compose them this way.

2) You can keep a lookup process somewhere, and just dole out integer

3) You can notice that local PIDs already only eat one word, and quit
playing translation games, because they're unnecessary.  (reference:
http://www.erlang.org/doc/efficiency_guide/advanced.html )

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.

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.

Micro-optimization is almost never the right way to push back machine
limits.  Consider working on your approach instead.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20081009/dbeaeb9f/attachment.htm>

More information about the erlang-questions mailing list