[Jprogramming] Faster array lookup? (poker hand evaluator)

Henry Rich henryhrich at gmail.com
Mon Jan 4 03:40:28 UTC 2016


This time seems way too high to me.

When I time a + a on 1e7 ints, I get about .03 sec.  When I time a { i. 
100 on 1e7 ints, I get about the same.

This program should be about 14 of those, and thus take around 0.5 sec.  
3 sec is way too high.

Can you dig into this and see where the time is going?


Henry Rich


On 1/3/2016 9:05 PM, Ryan Eckbo wrote:
> Henry's idea made the computation 10 times faster:
>
>       hands=. |: 53,.~ >:(1e7#7)?52
>   6!:2 'handvalues=. (HR {~ +)/ hands'
> 3.08429
>
> HANDTYPE=: <;._2 [0 : 0
> BAD
> High Card
> One Pair
> Two Pair
> Trips
> Straight
> Flush
> Full House
> Quads
> Straight Flush
> )
> HANDTYPE {~ _12 (33 b.)  10  {. handvalues  NB. right shift 12 bits to 
> get hand type id
> ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬─────────┬─────┬────────┐ 
>
> │Two Pair│One Pair│One Pair│Two Pair│One Pair│One Pair│One Pair│High 
> Card│Flush│One Pair│
> └────────┴────────┴────────┴────────┴────────┴────────┴────────┴─────────┴─────┴────────┘ 
>
> By the way you can also use this method to evaluate 5 or 6 card hands:
> hr7=: (HR {~ +)/@:(,&53)
> hr5or6=: HR {~ hr7
>
> I think this should be fast enough for my purposes, if not I'll either 
> write a C api
> as Raul suggested or test other evaluator implementations (like 
> http://suffe.cool/poker/evaluator.html,
> which is actually used to construct the HR lookup table, and is fast 
> for 5 card evaluations -- although
> I can't imagine it being faster than a lookup table).
>
> Here's an interesting fact: there are 2.5 millions 5 card hand 
> combinations but only 7462 distinct hand values.
> The hand values returned by HR aren't in this range but they do 
> guarantee that if HR[hand1_idx] > HR[hand2_idx]
> then hand1 beats hand2.
>
> Thanks for the help!
> Ryan
>
>
> On 3 Jan 2016, at 14:56, Ryan Eckbo wrote:
>
>> I've implemented the twoplustwo 7 card poker hand evaluator[1] in J 
>> but it's
>> slower than I expected.  The evaluator works by accepting an array of 7
>> integers between 1 and 52, representing a 7 card hand, and uses them 
>> as indices
>> in a lookup table, which returns the best 5 card hand's rank value.  
>> Here's the
>> C code that does this (HR is the lookup table):
>>
>> int LookupHand(int* pCards)
>> {
>> int p = HR[53 + *pCards++];
>> p = HR[p + *pCards++];
>> p = HR[p + *pCards++];
>> p = HR[p + *pCards++];
>> p = HR[p + *pCards++];
>> p = HR[p + *pCards++];
>>     return HR[p + *pCards++];
>> }
>>
>> My J version is:
>>
>> hr=: (HR {~ +)/@:(,&53)     NB. hr 1 5 9 12 20 25 42
>>
>> This is one of the fastest evaluators out there, for example a 
>> javascript version
>> can run at 20 million evaluations per second.  My J version takes 30 
>> seconds
>> to evaluate just 10 million hands:
>>
>> hands=. 53,.~ >: ? 1e7 7 $ 52  NB. 10 million hands, with initial 
>> index 53 added
>> 6!:2 '(HR {~ +)/"1 hands'  NB. 32.14 sec on a 2.8GHz Mac
>>
>> I wonder why it's slow and if there's a way to make it faster?
>>
>>
>> [1] 
>> https://github.com/christophschmalhofer/poker/blob/master/XPokerEval/XPokerEval.TwoPlusTwo.Test/test.cpp
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm



More information about the Programming mailing list