Tôi đang cố gắng sử dụng phương pháp "Trình đánh giá tay RayW" để có điểm kết hợp thẻ (5 thẻ tốt nhất trong số 7 thẻ). Tuy nhiên, tôi có một số vấn đề về hiệu suất với phương pháp này. Theo các nguồn tin - sử dụng cách tiếp cận này, nó phải có khả năng đánh giá hơn 300 triệu tay mỗi giây! Kết quả của tôi là 10 nhà máy trong 1,5 giây, chậm hơn nhiều lần.Đánh giá tay poker nhanh hơn
Ý tưởng đằng sau "RayW tay đánh giá" là như sau:
Hai cộng với hai đánh giá bao gồm một bảng tra cứu lớn chứa một số 32.000.000 mục (32.487.834 để được chính xác). Theo thứ tự để tra cứu một lá bài xì phé 7 lá bài đã cho, bạn theo dõi một lối đi qua bảng này, thực hiện một lần tra cứu trên mỗi thẻ. Khi bạn nhận được vào thẻ cuối cùng, giá trị để thu được là giá trị tương đương chính thức của Mặt
đây là cách mã trông giống như:
namespace eval
{
public struct TPTEvaluator
{
public static int[] _lut;
public static unsafe void Init() // to load a table
{
_lut = new int[32487834];
FileInfo lutFileInfo = new FileInfo("HandRanks.dat");
if (!lutFileInfo.Exists)
{throw new Exception("Handranks.dat not found");}
FileStream lutFile = new FileStream("HandRanks.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096);
byte[] tempBuffer = new byte[32487834 * 4];
lutFile.Read(tempBuffer, 0, 32487834 * 4);
fixed (int* pLut = _lut)
{ Marshal.Copy(tempBuffer, 0, (IntPtr)pLut, 32487834 * 4);}
tempBuffer = null;
}
public unsafe static int LookupHand(int[] cards) // to get a hand strength
{
fixed (int* pLut = _lut)
{
int p = pLut[53 + cards[0]];
p = pLut[p + cards[1]];
p = pLut[p + cards[2]];
p = pLut[p + cards[3]];
p = pLut[p + cards[4]];
p = pLut[p + cards[5]];
return pLut[p + cards[6]];
}
}
}
}
và đó là cách tôi thử nghiệm phương pháp này:
private void button4_Click(object sender, EventArgs e)
{
int[] str = new int[] { 52, 34, 25, 18, 1, 37, 22 };
int r1 = 0;
DateTime now = DateTime.Now;
for (int i = 0; i < 10000000; i++) // 10 mil iterations 1.5 - 2 sec
{ r1 = TPTEvaluator.LookupHand(str);} // here
TimeSpan s1 = DateTime.Now - now;
textBox14.Text = "" + s1.TotalMilliseconds;
}
Tôi tin rằng phương pháp này ban đầu được triển khai trong C++, nhưng n tuy nhiên C# port sẽ hoạt động nhanh hơn. Có cách nào để tôi có thể đến gần ít nhất 100 triệu tay trong một giây không?
gì tôi đã cố gắng cho đến nay:
- cố gắng sử dụng tĩnh, và các phương pháp không tĩnh - không có sự khác biệt.
cố gắng sử dụng tra cứu từ điển thay vì mảng
public void ArrToDict(int[] arr, Dictionary<int, int> dic) { for (int i = 0; i < arr.Length; i++) { dic.Add(i, arr[i]); } } public unsafe static int LookupHandDict(int[] cards) { int p = dict[53 + cards[0]]; p = dict[p + cards[1]]; p = dict[p + cards[2]]; p = dict[p + cards[3]]; p = dict[p + cards[4]]; p = dict[p + cards[5]]; return dict[p + cards[6]]; }
Thời gian đã qua 10 nhà máy của bàn tay là gần 6 chậm hơn lần ..
Theo một người - anh nâng tỷ số hiệu suất của 200 nhà máy bằng cách xóa mã "không an toàn". Tôi đã cố gắng làm điều tương tự nhưng kết quả gần như giống nhau.
public static int LookupHand(int[] cards) { int p = _lut[53 + cards[0]]; p = _lut[p + cards[1]]; p = _lut[p + cards[2]]; p = _lut[p + cards[3]]; p = _lut[p + cards[4]]; p = _lut[p + cards[5]]; return _lut[p + cards[6]]; }
Dưới đây là đoạn trích:
Sau khi loại bỏ những phần mã "không an toàn" và một số điều chỉnh nhỏ trong cáC# phiên bản c nó bây giờ cũng khoảng 310 mio là.
có cách nào khác để tăng hiệu suất của hệ thống xếp hạng tay này không?
Bạn đã thử chạy trong chế độ phát hành chưa? Nó có thể hoạt động nhanh hơn sau đó, bởi vì mã được tối ưu hóa. –
tệp .dat chứa tất cả các mục này có kích thước 130 Mb. Tuy nhiên, P4 PC có 1-2 gigs ram không có bất kỳ vấn đề gì. Tôi có 4 hợp đồng biểu diễn, vì vậy RAM không phải là vấn đề lớn. – Alex
@MichalB. bây giờ là 200 mili giây !! Cảm ơn nhiều. Tôi sẽ không loại bỏ vấn đề này .. có thể có một số cải tiến khác có thể được thực hiện .. Cảm ơn bạn, một lần nữa !! – Alex