This repository contains tests and benchmarks to compare various chess implementations against each other. More precisely, the following things are implemented:
Tests:
Benchmarks:
The following implementations are tested now, with different support level:
Implementation | perft | hperft | selftest |
---|---|---|---|
chess | ✔️ | ✔️ | ✔️ |
owlchess | ✔️ | ✔️ | ✔️ |
shakmaty | ✔️ | ✔️ | ❌ |
cozy-chess | ✔️ | ✔️ | ❌ |
pleco | ✔️ | ✔️ | ❌ |
Just do
$ cargo test
You will need Python 3 to do this.
First, install the pre-requisites:
$ pip install matplotlib
$ cargo install cargo-criterion
Then, do the following:
$ cd run_perft
$ ./run.py
This will run the benchmarks and build nice plots into run_perft/perft.svg
and run_perft/hperft.svg
(for Perft and Hperft, respectively).
You can also run benchmarks via raw cargo criterion
, but in this case you won't obtain plots comparing different implementations.
You can easily add your chess implementation (if it's written in Rust, of course).
- Add your implementation to
src/impls
. See existing implementations as an example. You need to implementTest
for selftest andPerft
for Perft/Hperft. - To add your implementation to Perft/Hperft tests and benchmarks, modify
impls::all_perft
. - To add your implementation to selftest, modify
run
function in the binary and add a new test intotests/selftest.rs
. - If your chess implementation exists as a crate on crates.io, then feel free to submit a PR :)
- Enjoy ;)
This repository is licensed under GPLv3 (or any later version). Each of the chess implementations tested here are subject to its own license.
Hperft (honest performance test, or hash-based performance test) is another way to test correctness and performance of chess implementations. Unlike regular Perft, it doesn't calculate number of positions, but it calculates sum of hashes over all the positions instead. The hashes involve bitboards, but the fastest implementations already use bitboards for move generation, don't they?
The difference is that Perft is not fair to use when comparing legal move generators with pseudo-legal ones. If you have a fully legal move generator, then you can just generate all the moves on the last depth, but don't try to apply them. On the other hand, this doesn't work well with pseudo-legal generators, which will apply all the moves even on the last depth to perform legality check. Hperft solves the issue by forcing implementations with legal move generators to make all the moves even on the last depth.
The downside is that Hperft more measures the speed of applying moves rather than the speed of generating moves. So, a better benchmark, which simulates workload of a typical chess engine more precisely, is still needed.
Benchmarks were run on the following crate versions:
chess
3.2.0owlchess
0.2.1shakmaty
0.21.2cozy-chess
0.2.2pleco
0.5.0
The CPU is AMD Ryzen 7 5700U, with 256 KB of L1 cache, 4 MB of L2 cache, and 8 MB of L3 cache.
The results are provided below. If you want a machine-readable version of the results, see run_perft/results.json
.