如何解决c++ 从字符串到位板的转换和返回优化
我正在处理一个作为字符串接收的游戏状态,需要将其转换为 bitboard。我相信我现在有一个功能可以实现这一点,但想知道如何优化它以加快执行速度?我最初从一个带有以下想法的循环开始:
for (i = 0; i < 23; ++i)
{
if (s.at(n) == 'x') set bit[2],// Start with x as there are more x's
else if(s.at(n) == 'W') set bit[0],// W next as W goes first
else set bit[1] // B last
}
但我认为我可以展开循环并跳过“i”的比较和递增。这样做之后,我想我可以删除最后一个对“B”的检查,然后接受 W | 的赞美。 x 并从中减去 4286578688 只给我 23 位。这给了我以下代码:
std::string board = "xBWxWxBWxWxxBxxxWxBxxBx"; // String to convert to bitboard
unsigned int bit; // Integer used for parsing values
unsigned int boards[3] {0,0}; // W in [0],B in [1],& x in [2]
if (board.at(0) == 'x') { boards[2] |= (1 << 22); } else if (board.at(0) == 'W') { boards[0] |= (1 << 22); }
⋅
⋅
⋅
if (board.at(22) == 'x') { boards[2] |= (1 << 0); } else if (board.at(22) == 'W') { boards[0] |= (1 << 0); }
boards[1] = ~(boards[0] | boards[2]) - 4286578688; // Take W's & x's compliment - 4286578688 to get 2163730
printf("%d | %d | %d\n",boards[0],boards[1],boards[2]); // Expected Output: "1351744 | 2163730 | 4873133"
是否有任何其他技巧可以进一步优化此过程以提高速度?我不太关心文件大小。
最后,我将如何将板 [W,B,x] 转换回字符串? (例如,玩家“W”在位置 22 上添加了一个棋子,结果是 boards[] = {1351745,2163730,4873132}
。如何将其转换为:board = xBWxWxBWxWxxBxxxWxBxxBW
?)
char state[23];
for (int i = 0,j = 22; i < 23; ++i,--j) {
if (boards[2] & (1 << j)) { state[i] = 'x'; } else if (boards[0] & (1 << j)) { state[i] = 'W'; } else { state[i] = 'B'; }
}
解决方法
你在评论中提到你是新手。我认为您需要具备大量背景知识才能做出有关优化的明智决策。
首先,编译器是很好的优化器。他们内置了控制流分析、内联、执行重新排序等等。它们可以根据 c++ 标准提供的保证进行优化。查找未定义的行为优化和优化以及指针别名作为了解编译器可以和不能为优化做什么的起点。
其次,如果不进行基准测试,就无法知道您的更改是否真的提高了程序的速度。就像您提到的那样,分析器可以帮助您找出程序中花费的时间。
第三,您提到您听说过“字符串很慢”。你应该问的一个问题是“与什么相比?” std::string
数据在堆上分配(除非它符合短字符串优化的条件,这是一些编译器可以为您做的另一件事)。我认为慢意味着它必须从堆中加载并在增长字符串时进行新的分配。分配很慢,为了速度,应该尽可能避免。您可以确定的一件事是 std::string::reserve
您希望字符串采用的最大大小。这将分配一次内存,而不是在您添加内存时动态增长它,从而导致一次或多次分配。查找堆栈与堆、分配成本和缓存未命中。
TL;DR:基准测试和实验,在尝试超越编译器之前增长您的知识。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。