Skip to content

Conversation

@luccabb
Copy link
Owner

@luccabb luccabb commented Jan 20, 2026

Summary

  • Use Zobrist hash instead of FEN string for evaluation cache keys (faster integer hashing vs string comparison)
  • Add cache size limit (1M entries) to prevent unbounded memory growth during long searches
  • Optimize board_evaluation() to iterate over actual pieces (~16-32) instead of all 64 squares

Details

The board evaluation function is called frequently during search. These optimizations reduce overhead:

  1. Zobrist hashing: chess.polyglot.zobrist_hash() returns an integer, which is faster to hash and compare than FEN strings
  2. Cache eviction: Simple clear-on-full policy prevents memory exhaustion in long games
  3. Piece iteration: Using board.pieces(piece_type, color) returns only occupied squares, reducing iterations by 50-75%

Test plan

  • All 64 unit tests pass
  • No changes to search behavior, only evaluation speed

🤖 Generated with Claude Code

@luccabb luccabb force-pushed the feature/psqt-evaluation-performance branch from bca3f3e to d7df55a Compare January 21, 2026 06:43
@luccabb luccabb changed the title [1/9] Improve PSQT evaluation performance [1/7] Improve PSQT evaluation performance Jan 21, 2026
Performance optimizations for board evaluation:

- Use Zobrist hash instead of FEN string for cache keys (faster hashing)
- Add cache size limit (1M entries) to prevent unbounded memory growth
- Optimize board_evaluation() to iterate over pieces instead of all 64 squares
  - Typically 16-32 pieces vs always 64 squares
  - Reduces unnecessary iterations by ~50-75%

These changes improve evaluation speed without affecting correctness.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@luccabb luccabb force-pushed the feature/psqt-evaluation-performance branch from d7df55a to e21928a Compare January 21, 2026 07:33
@luccabb luccabb changed the title [1/7] Improve PSQT evaluation performance [1/6] Improve PSQT evaluation performance Jan 21, 2026
@github-actions
Copy link

🔬 Stockfish Benchmark Results

vs Stockfish Skill Level 3

Metric Wins Losses Draws Total Win %
Overall 32 60 8 100 32.0%
As White 15 31 4 50 30.0%
As Black 17 29 4 50 34.0%

Non-checkmate endings:

  • Draw by 3-fold repetition: 6

vs Stockfish Skill Level 4

Metric Wins Losses Draws Total Win %
Overall 25 70 5 100 25.0%
As White 11 37 2 50 22.0%
As Black 14 33 3 50 28.0%

Non-checkmate endings:

  • Draw by 3-fold repetition: 5

vs Stockfish Skill Level 5

Metric Wins Losses Draws Total Win %
Overall 9 83 8 100 9.0%
As White 6 39 5 50 12.0%
As Black 3 44 3 50 6.0%

Non-checkmate endings:

  • Draw by 3-fold repetition: 5
Configuration
  • 5 chunks × 20 rounds × 3 skill levels = 300 total games
  • Each opening played with colors reversed (-repeat) for fairness
  • Moonfish: 60s per move
  • Stockfish: 60+5 time control

@greptile-apps
Copy link

greptile-apps bot commented Feb 2, 2026

Greptile Overview

Greptile Summary

This PR optimizes the board evaluation performance through three key improvements:

  • Replaced FEN string-based cache keys with Zobrist hash integers for faster lookups
  • Added 1M entry cache limit with clear-on-full eviction to prevent memory exhaustion
  • Refactored evaluation loop to iterate over actual pieces (16-32) instead of all 64 squares

The changes are well-implemented and maintain evaluation correctness. The optimizations reduce computational overhead without altering search behavior. The cache eviction strategy is simple but effective for preventing unbounded memory growth during extended searches.

Confidence Score: 5/5

  • Safe to merge - performance optimizations with no behavioral changes
  • All optimizations are sound: Zobrist hashing is standard in chess engines, piece iteration reduces unnecessary work, and cache limiting prevents memory issues. No logical errors or breaking changes detected.
  • No files require special attention

Important Files Changed

Filename Overview
moonfish/psqt.py Optimized evaluation caching with Zobrist hashing and piece iteration; no logical issues found

Sequence Diagram

sequenceDiagram
    participant Engine as Alpha-Beta Engine
    participant Cache as board_evaluation_cache
    participant Eval as board_evaluation
    participant Board as chess.Board
    
    Engine->>Cache: call board_evaluation(board)
    Cache->>Board: zobrist_hash(board)
    Board-->>Cache: int hash key
    
    alt Cache hit
        Cache-->>Engine: return cached value
    else Cache miss
        alt Cache full (≥1M entries)
            Cache->>Cache: clear entire cache
        end
        Cache->>Eval: call board_evaluation(board)
        Eval->>Eval: get_phase(board)
        loop For each piece type
            Eval->>Board: pieces(piece_type, WHITE)
            Board-->>Eval: SquareSet of white pieces
            loop For each white piece
                Eval->>Eval: mg_white += table[square^56] + value
                Eval->>Eval: eg_white += table[square^56] + value
            end
            Eval->>Board: pieces(piece_type, BLACK)
            Board-->>Eval: SquareSet of black pieces
            loop For each black piece
                Eval->>Eval: mg_black += table[square] + value
                Eval->>Eval: eg_black += table[square] + value
            end
        end
        Eval->>Eval: calculate tapered eval based on phase
        Eval-->>Cache: evaluation score
        Cache->>Cache: store in cache[hash]
        Cache-->>Engine: return evaluation score
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants