c++从字符串到Bitboard的转换和反向优化

c++ Conversion from String to Bitboard and Back Optimization

本文关键字:优化 转换 字符串 Bitboard c++      更新时间:2024-09-26

我正在处理一个游戏状态,该状态作为字符串接收,需要转换为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, 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 | %dn",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:基准测试和实验,在你试图智胜编译器之前增长你的知识。