You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Basic 2010国际象棋递归搜索中List复用的性能优化技术问询

解决方案:复用List并在递归后恢复状态

Hey,针对你在VB2010象棋程序递归搜索里遇到的List复用和性能问题,我有几个实用的解决方案,尤其是能让你复用同一个List同时保证递归前后状态一致的方法,一起来看看:

核心思路:记录List初始长度,递归后截断恢复

频繁新建List会导致大量内存分配和GC压力,这正是你程序变慢的原因。我们可以复用同一个List,在递归调用前记录List的当前长度,递归返回后把List截断回初始长度,这样就模拟了ByVal按值传递的效果,同时完全避免了新建List的开销。

具体代码修改步骤

首先,你需要调整calculate_all_moves的实现:原来的代码是返回新List并赋值给all_moves_list,这会丢失原List的引用,无法后续恢复。请把它改成直接往传入的List中添加当前局面的合法走法(比如改成Sub过程,或者让函数在现有List基础上追加元素)。

然后修改你的递归过程:

Sub recurvive_search(ByVal the_board(,) As theboardclass, ByVal depth As Integer, ByRef depth_count() As Integer, ByVal whosgo__ As Integer, ByRef all_moves_list As List(Of A_Move))
    If depth = 3 Then
        depth_count(4) += 1
    Else
        ' 1. 记录递归前List的初始长度
        Dim initialListCount As Integer = all_moves_list.Count
        
        ' 2. 计算当前局面的所有走法,直接添加到现有List中(已调整calculate_all_moves逻辑)
        calculate_all_moves(the_board, whosgo__, all_moves_list)
        
        ' 3. 遍历本次新增的走法(从初始长度到List末尾)
        For i As Integer = initialListCount To all_moves_list.Count - 1
            Dim currentMove As A_Move = all_moves_list(i)
            If Not IsNothing(currentMove.sym_of_moving_piece) Then
                depth_count(depth) += 1
                ' 执行走法,更新棋盘
                the_board = Me.change_board(the_board, the_board(currentMove.From_x, currentMove.From_Y).getsym, the_board(currentMove.From_x, currentMove.From_Y).getteam, currentMove.New_x, currentMove.New_Y, currentMove.From_x, currentMove.From_Y)
                ' 切换玩家
                whosgo__ = switchgoes(whosgo__)
                
                ' 递归调用,传递同一个List
                recurvive_search(the_board, depth + 1, depth_count, whosgo__, all_moves_list)
                
                ' 恢复玩家和棋盘状态
                whosgo__ = switchgoes(whosgo__)
                the_board = Me.undo_move(the_board, currentMove)
            End If
        Next
        
        ' 4. 递归返回后,移除本次添加的所有走法,恢复List到初始状态
        all_moves_list.RemoveRange(initialListCount, all_moves_list.Count - initialListCount)
    End If
End Sub

为什么这个方法高效?

  • 避免内存分配:全程复用同一个List,没有频繁的New List操作,大幅减少GC的工作负担。
  • 批量操作更高效:RemoveRange是批量移除元素的方法,比逐个移除元素的性能高很多,对List的整体性能影响极小。

额外性能优化建议

  1. 预先设置List的Capacity:在初始化all_moves_list时,设置一个足够大的初始容量(比如国际象棋单次最多可能有200+种合法走法),避免List在添加元素时频繁扩容:
    Dim all_moves_list As New List(Of A_Move)(256) ' 设置初始容量为256
    
  2. 检查calculate_all_moves的效率:确保这个方法本身没有冗余计算,比如重复遍历棋盘、不必要的对象创建等,这也是递归性能的关键环节。

内容的提问来源于stack exchange,提问作者lewis peck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:37:42