我目前正在为游戏编写 MCTS AI 程序,我想优化 CPU 瓶颈。一种方法大约需要所有处理的 20%,并将 2D 字符串上某个位置上的棋子/底座返回给所属的团队。碱基格式为“b:000”,其中 000 是 teamId。片段的格式为“p:000_1”,其中 000 是 teamId。我想做的就是尽可能高效地从 Id 字符串中获取 000。
目前我的代码如下:
public static int getOccupantTeam(String[][] grid, int[] pos, StringBuilder sb) {
sb = sb.delete(0, sb.length()).append(grid[pos[0]][pos[1]]);
int indexUnderscore = sb.indexOf("_");
return Integer.parseInt(sb.substring(sb.indexOf(":")+1, indexUnderscore == -1 ? sb.length() : indexUnderscore));
}
StringBuilder 是为了减少创建的对象数量,因为我可以创建一次并根据需要经常使用它。 有什么方法可以让我的代码更高效吗?
正如评论所说,你最好修复整体设计。使用专用对象而不是格式化字符串。
但是如果你想保留逻辑:
令人震惊的是这里完全毫无意义地使用了
StringBuilder
。您在开始时清空构建器(通过 sb.delete(0, sb.length())
),然后将单个字符串复制到其中,只是为了对 StringBuilder
执行操作,您可以首先对原始 String
执行操作。
除此之外,由于下划线的索引预计位于冒号之后,因此您可以先搜索冒号,然后只搜索该位置之后的下划线。
public static int getOccupantTeam(String[][] grid, int[] pos, StringBuilder sb) {
String s = grid[pos[0]][pos[1]];
int start = s.indexOf(":") + 1, indexUnderscore = s.indexOf("_", start);
return Integer.parseInt(
s.substring(start, indexUnderscore == -1? s.length(): indexUnderscore));
}
当然,您现在可以删除过时的
StringBuilder
参数。
如果您使用的是 Java 9 或更高版本,则可以省略
substring
操作:
public static int getOccupantTeam(String[][] grid, int[] pos) {
String s = grid[pos[0]][pos[1]];
int start = s.indexOf(":") + 1, indexUnderscore = s.indexOf("_", start);
return Integer.parseInt(
s, start, indexUnderscore == -1? s.length(): indexUnderscore, 10);
}
Integer.parseInt(CharSequence s, int beginIndex, int endIndex, int radix)
删除
b:
和 p:
前缀,因为字符串的长度将基础与片段区分开来。三个字代表一个底座,超过3个代表一块。
要获取团队编号,您知道它始终是前三个字符。
int teamId = Integer.parseInt( string.substring( 0 , 2 ) ) ;
但正如其他人所建议的,您应该使用智能对象而不是哑字符串。