Estoy tratando de utilizar el enfoque del "evaluador de la mano RayW" para obtener una puntuación de combinación de tarjetas (5 mejores tarjetas de un total de 7). Sin embargo estoy teniendo algunos problemas de rendimiento con este método. Según las fuentes: ¡con este enfoque, debe ser posible evaluar más de 300 mil manos por segundo! Mi resultado es 10 molinos en 1.5 segundos, que es mucho más lento.Evaluación más rápida de la mano de póquer
La idea detrás de "mano evaluador RayW" es el siguiente:
El evaluador dos más dos consta de una tabla de consulta que contiene gran unos treinta y dos millones de entradas (32.487.834 para ser exactos). Para obtener y buscar una mano de poker de 7 cartas determinada, trace una ruta a través de esta tabla , realizando una búsqueda por tarjeta. Cuando se llega a la última carta, el valor así obtenido es el valor oficial de la equivalencia de la mano
aquí es cómo se ve un código como:
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]];
}
}
}
}
y así es como me probar este enfoque:
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;
}
Creo que este método se implementó originalmente en C++, pero n sin embargo, el puerto C# debería funcionar más rápido. ¿Hay alguna forma de cómo puedo acercarme a al menos 100 millones de manos en un segundo?
lo que he intentado hasta ahora:
- intentado usar estático, y los métodos no estáticos - no hay diferencia.
intentado usar búsqueda de diccionario en lugar de gama
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]]; }
tiempo transcurrido durante 10 molinos de manos es casi 6 veces más lento ..
De acuerdo con una persona - puso en el rendimiento en 200 fábricas eliminando el código "inseguro". Traté de hacer lo mismo, pero los resultados son casi los mismos.
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]]; }
Esta es la cita:
Después de quitar las partes de código "inseguros" y algunos pequeños ajustes en la versión # c es ahora también alrededor de 310 mio.
¿Hay alguna otra forma de aumentar el rendimiento de este sistema de clasificación manual?
¿Ha intentado ejecutar en modo de lanzamiento? Podría funcionar más rápido, porque el código está optimizado. –
el archivo .dat que contiene todas estas entradas es de 130 Mb de tamaño. Sin embargo, las PC P4 con 1 o 2 gigas de ram no tuvieron ningún problema. Tengo 4 conciertos, por lo que la RAM no debería ser un gran problema. – Alex
@MichalB. ¡Son 200 milisegundos ahora! gracias un montón. No eliminaré este problema ... tal vez haya más mejoras que puedan hacerse ... ¡¡Gracias de nuevo !! – Alex