Arrays 快速高效的数组查找和修改
我一直想知道以下两种方法中哪一种更快或更好 我目前的方法 我正在开发一个国际象棋游戏,棋子以数字(实际上是字节来保存内存)的形式存储到一维数组中。在数组中有一个与索引相对应的光标位置。访问数组中当前位置的工件很容易(Arrays 快速高效的数组查找和修改,arrays,lookup,Arrays,Lookup,我一直想知道以下两种方法中哪一种更快或更好 我目前的方法 我正在开发一个国际象棋游戏,棋子以数字(实际上是字节来保存内存)的形式存储到一维数组中。在数组中有一个与索引相对应的光标位置。访问数组中当前位置的工件很容易(piece=pieces[cursorPosition]) 问题在于,要获取用于检查移动是否有效的x和y值,需要除法和模运算符(x=cursorPosition%8;y=cursorPosition/8) 同样,当使用x和y来检查移动是否有效时(你必须这样做,因为这样做的原因会填满整
piece=pieces[cursorPosition]
)
问题在于,要获取用于检查移动是否有效的x和y值,需要除法和模运算符(x=cursorPosition%8;y=cursorPosition/8
)
同样,当使用x和y来检查移动是否有效时(你必须这样做,因为这样做的原因会填满整个页面),你必须做一些类似的事情-纯粹作为一个例子-if片段[y*8+x]!=0:movePiece=False
。最明显的问题是必须执行y*8+x
多次才能访问阵列
最终,这意味着获得一个片段很简单,但是获得x和y需要额外的内存和非常少的时间来计算每一轮
更传统的方法
使用二维数组,可以更轻松地实现上述过程,但工件查找现在变得更困难,并且使用了更多内存。(即piece=pieces[cursorPosition[0]][cursorPosition[1]]
或piece=pieces[x][y]
)
我不认为这是更快的,它肯定不会看起来更少的内存密集型
目标
我的最终目标是拥有尽可能快、占用内存最少的代码。这将是为unix终端开发的(如果我能想出如何使用Ansi转义序列表示不带颜色的片段,则可能是Windows CMD),我将使用安全的(使用协议和结构加密)我不知道人们会有多少内存,他们的计算机会有多快,他们的互联网连接会有多强
我也只是想学着用最好的方式去做,看看能不能做到
-
我想我的问题是:
假设涉及移动验证的计算稍微多一些(这意味着必须大量使用y*8+x
),上述哪种方法更好
或
是否有一种方法既包含了一维数组的优点,又包含了二维数组的优点,并且没有我描述的那么多回退?首先,您应该分析代码,以确保这确实是一个值得花费时间的瓶颈 其次,如果将位置表示为无符号字节,则将其分解为X和Y坐标将非常快。如果我们使用以下C代码:
int getX(unsigned char pos) {
return pos%8;
}
我们使用gcc 4.8-O2获得以下组件:
getX(unsigned char):
shrb $3, %dil
movzbl %dil, %eax
ret
getY(unsigned char):
movl %edi, %eax
andl $7, %eax
ret
如果我们得到Y坐标,则:
int getY(unsigned char pos) {
return pos/8;
}
我们使用gcc 4.8-O2获得以下组件:
getX(unsigned char):
shrb $3, %dil
movzbl %dil, %eax
ret
getY(unsigned char):
movl %edi, %eax
andl $7, %eax
ret
这个问题没有简单的答案;这完全取决于你花在优化上的时间 在某些体系结构上,二维阵列可能比一维阵列工作得更好。在其他体系结构上,位图整数可能是最好的 不要担心除法和乘法。 你在除以,调制,乘以8。 这个数字是二的幂,因此任何计算机都可以使用位运算来获得结果
- (x*8)与(x>3)相同
if(position & 0x88)
{
/* move is illegal */
}
else
{
/* move is legal */
}
。。。或者
if(0 == (position & 0x88))
{
/* move is legal */
}
“position”(索引)应该是一个无符号字节(uint8_t in C)。这样,您就不必担心指向缓冲区之外
有些人通过使用64位位图整数来优化他们的象棋引擎。
虽然这有利于快速比较位置,但也有其他缺点;例如,检查骑士的举动是否合法。
不过,说哪一个更好并不容易
我个人认为,一般来说,一维数组可能是最好的方法。
我建议您熟悉(非常熟悉)AND、OR、XOR、位移位和旋转
有关更多信息,请参见。首先,您翻转了x和y。x=pos%8用于获取该行中的x索引,y=pos/8用于获取该行。我知道我可以写一个方法,但那会更慢,而且我还必须做很多,因为当我检查一堆位置,看它们是否包含可以攻击国王的部分时,例如,我必须做两个循环,就像在2d数组中一样,但是对于每个索引,我也必须一遍又一遍地重复你上面写的方法。哦,也许你只是错误地命名了这些方法。。。盖蒂·雷图