Match many patterns in Haskell efficiently

I was thinking about using Haskell for a game server, but when coding, I found that I was looking at the part where I parse packages that think "wow, this will lead to a lot of pattern matching." This, seeing the number of matches that need to be done, is a lot (go there, attack it, mine, open it, etc.).

What am I doing:

  • Receive package
  • Parse the packet header into a hexadecimal string (for example, "02B5")
  • Get the remaining data from the package
  • ParseIO header
  • Call the corresponding function with the contents of the package.

It would be easy to map the String โ†’ method, but the methods have a different number of parameters.

I thought of two simple ways to compare the patterns shown below.

#1 packetIO :: String -> IO () packetIO packet = case packet of "02B5" -> function1 "ADD5" -> function2 ... and so on #2 packetIO :: String -> IO () packetIO "02B5" = function1 packetIO "ADD5" = function2 ... and so on 

For, looking at the performance and coding style, is there a better way to handle packets received from the client?

If you have any resources or links that I could not find, please indicate their direction to me!

EDIT 130521 :

Both alternatives listed below seem to be a good choice. Just waiting for the answer to my questions in the comments before choosing what was the best solution for me.

  • Saving (ByteString โ†’ Function) in the map structure. O (log n)
  • Converting ByteString to Word16 and pattern matching. O (log n) through the tree or O (1) through lookup tables

EDIT 130521 :

We decided to match the patterns with Word16, as Philip JF said. Both are great alternatives, and although my hunch is the same, Map may be faster because I don't need to convert to Word16, another option gave more readable code for my use:

 packetIO 0x02B5 = function1 packetIO 0xADD5 = function2 etc 
+6
source share
2 answers

Why not parse the numbers ( Word16 in Data.Word ?), And then do a comparison with that, instead of using strings? Haskell supports hexadecimal literals ...

+14
source

Both of your functions are equivalent. The compiler assigns the second first. Matching patterns is syntactic sugar for case .

case is optimal for this kind of thing. It compiles to a jump table, which is O (1). This means that both of the solutions you specified are optimal.

As for the coding style, both styles are perfectly idiomatic. I personally prefer case pattern matching, but I know that many other people prefer pattern matching for top-level functions.

+10
source

Source: https://habr.com/ru/post/945467/


All Articles