我一直想知道以下两种方法中的哪一种更快或更好。
我开发了一个国际象棋游戏,这些棋子被存储为数字(实际上是保存内存的字节)到一维数组中。光标的位置对应于数组中的索引。要在阵列中的当前位置访问该块很容易(piece = pieces[cursorPosition]
)。
问题是要获取x和y值以检查移动是否为有效移动需要除法和模运算符(x = cursorPosition % 8; y = cursorPosition / 8
)。
同样,当使用x和y来检查移动是否有效时(由于填充整个页面的原因,你必须这样做),你必须做类似的事情 - 纯粹作为一个例子 - if pieces[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)我将使用安全(加密协议和结构)TCP连接来连接人p2p下国际象棋或其他东西,我不知道人们会有多少记忆,计算机的速度有多快,或者他们的网络连接有多强。
我也想学习以最好的方式做到这一点,看看是否可以做到。
我想我的问题是以下之一:
假设涉及移动验证的计算稍多(这意味着必须经常使用y * 8 + x
),上述哪种方法更好?
或
是否有一种方法既包含1d和2d数组的优点,又没有我描述的那么多缺点?
答案 0 :(得分:2)
首先,您应该对代码进行分析,以确保这确实是一个值得花时间的瓶颈。
其次,如果你将你的位置表示为无符号字节,将其分解为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
如果我们得到Y坐标:
int getY(unsigned char pos) {
return pos/8;
}
我们使用gcc 4.8 -O2获得以下程序集:
getY(unsigned char):
movl %edi, %eax
andl $7, %eax
ret
答案 1 :(得分:1)
这个问题没有简短的答案;这一切都取决于你花在优化上的时间。
在某些体系结构中,二维数组可能比一维更好。在其他体系结构中,位图整数可能是最好的。
不要担心分裂和乘法。 你正在划分,调制和乘以8。 这个数字是2的幂,因此任何计算机都可以使用按位运算来实现结果。
这些操作通常在单个时钟周期内执行。在许多现代架构中,它们可以在不到一个时钟周期内执行(包括ARM架构)。 不要担心使用按位运算符而不是*,%和/。如果您使用的编译器不到十年,它将为您优化并使用按位操作。
您应该关注的是,例如,找出移动是否合法是多么容易。这将有助于您的计算机玩家“快速思考”。
如果您使用的是8 * 8阵列,那么通过检查是否只更改了x或y,您可以轻松查看城堡的移动位置。如果检查女王,则X必须相同或移动与Y位置相同的步数。
如果你使用一维数组,你也有优势。
但在性能方面,使用16x16阵列或1x256阵列可能是个不错的主意。 用0x80值填充整个数组(例如“非法位置”)。然后用0x00填写合法字段。
如果使用1x256阵列,则可以检查索引的第3位和第7位。如果设置了任何一个,那么该位置在董事会之外。 测试可以这样做:
if(position & 0x88)
{
/* move is illegal */
}
else
{
/* move is legal */
}
......或......
if(0 == (position & 0x88))
{
/* move is legal */
}
'position'(索引)应该是无符号字节(C中的uint8_t)。这样,您就不必担心指向缓冲区外。
有些人通过使用64位位图整数来优化他们的国际象棋引擎。 虽然这有利于快速比较位置,但它还有其他缺点;例如,检查骑士的举动是否合法。 但是,要说哪个更好是不容易的。
就个人而言,我认为一维数组通常可能是最好的方法。 我建议熟悉(非常熟悉)AND,OR,XOR,位移和旋转。
有关详细信息,请参阅Bit Twiddling Hacks。