
Hello Joel, Tuesday, December 27, 2005, 6:24:56 PM, you wrote:
no problem. my library handle about 10-15mb/s, and i think that speed can be doubled by using unboxed ints
JR> Would you like to present your version of the timeleak code plus JR> statistics from a test run? do it yourself. i can help you if you want to try JR> Please make sure that you have bots reading from the file all at the JR> _at the same time_, not sequentially. you must decide what is your problem - unpickling, multithreading, someone else. are you waiting what i can do it for you? :)
these delays says nothing about speed. you are mixing two things - your end goal is to make delays short, but your instrument - speeds of different processes and to decide what you need to optimize you must calc these speeds separately. without it, your "optimization" is just random game
JR> I need to reduce the overall delay. Individual delays do me no good. JR> Show me a 1-2s delay in the "timeleak" unstuff code then I will be JR> convinced. if, for example, the game work too slow on your computer, you must decide what is a problem - CPU, graphics card, lack of memory or something else and upgrade this detail first. you can, for example, buy the graphics card for $1000 but still have just memory swapping as main problem. believe you or not, but the same holds true in programming - the key to right optimization is to find "bottlenecks", not optimizing everything you can. spending several weeks to random optimization is like buying a gold computer case trying to speed up the game :) sorry, but your negative results say more about you than about GHC or Haskell. you are working 3 months but still don't know what is a bottleneck in your program!
JR> Each bot is given 5, 15 or 35 seconds to respond by the poker server
so you don't need to create complex timer thread machinery, just use 3 threads which proceed requests in FIFO order
JR> Socket read is a blocking operation. An easy way to handle a blocking JR> read is to launch a thread that reads from a socket and posts packets JR> somewhere once they are retrieved. I cannot handle large numbers of JR> bots if I block on a socket read. i say about timer thread. you created complex design using Map to find first event to complete, but instead you can use just 3 timer threads, each one serving a fixed timing interval. each thread will serve requests just in the order they arrive
i think that you will get just the same problems as with Haskell and forced to switch back because it's easier to low-level optimize in Haskell than in Erlang
JR> Absolutely not. I wrote a poker server in Erlang (see the openpoker/ it's strange what your pocker server don't required the same pickler library as client. this 50k structure is constructed on the server end, i'm right? JR> Because I have 150 records with a lot of fields and writing separate JR> code for pickling and unpickling is a nightmare? these concrete definitions are nightmare? :) let's compare them with that clear and obvious code: puTableInfo :: PU TableInfo puTableInfo = sequ ti_1 endian64 (\a -> sequ ti_2 endian16 (\b -> sequ ti_3 endian16 (\c -> sequ ti_4 byte (\d -> sequ ti_5 wstring (\e -> sequ ti_6 endian32 (\f -> sequ ti_7 (enum endian16 :: PU GameType) ........ (\w -> lift $! TableInfo a b c d e f g h i j k l m n o p q r v w ))))))))))))))))))))
for example, one of these solutions looks like this:
instance Binary TableInfo where put_ bh (TableInfo a b c d) = put_ bh (a,b,c,d) get bh = do (a,b,c,d) <- get bh; return (TableInfo a b c d)
instance Binary GameType where put_ bh = putWord16 bh . fromEnum get = liftM toEnum . getWord16
JR> This gets tedious very quickly. no, type classes allow code economy comparing to combinators you use. you need to define only one time how to process each type. just one definition for all lists, one for all Word16, one for all GameType and so on. all the records defined by the easy code like this one for TableInfo -- Best regards, Bulat mailto:bulatz@HotPOP.com