The date that C# becomes faster than languages such as C and Rust will be the day that pigs fly and hell freezes over. I will probably stop programming and switch to psychology or something. I'll have to profile the engine again to see if I can improve speed somewhere, but I doubt it, to be honest.
Agreeing to that would just mean that Leorik could be even faster if I did the same thing in C or Rust. But we - you and I - are not doing the same thing so comparing speed and drawing conclusions about what programming language is faster is a bit... unscientific.
With regard to the speed increase... it looks like as if Leorik is now counted nodes that are entered but exited really quickly due to a cutoff; so they don't do any actual work. That would explain the speed increase. Pruning can make the engine visit more nodes/second because it cuts them faster, which increases NPS, but it does not make the engine any faster.
That I count these nodes in qsearch is not new to Leorik 1.5. I counted exactly the same way in version 1.0... and afaik everybody counts those nodes. You do too!
Code: Select all
pub fn quiescence(mut alpha: i16, beta: i16, pv: &mut Vec<Move>, refs: &mut SearchRefs) -> i16 {
// We created a new node which we'll search, so count it.
refs.search_info.nodes += 1;
// Do a stand-pat here: Check how we're doing, even before we make
// a move. If the evaluation score is larger than beta, then we're
// already so bad we don't need to search any further. Just return
// the beta score.
let eval_score = evaluation::evaluate_position(refs.board);
if eval_score >= beta {
return beta;
}
}
The cheapest way to raise the node Counter in Leorik is also a very cheap node in Rustic too. But how would you justify not counting them?
How much Elo did you get from History, separately, before you implemented LMR? Or didn't you test that?
I talked about it briefly in the Version 1.4 section. I tried a dozen different variants but didn't manage to get over 10 ELO and you know how hard it is to proof that +10 ELO isn't a statistical fluke. So it's safe to say that for Leorik history heuristics are so costly performance wise that they need late move reductions before they become worth it. But every engine is different!
I have now made the test of measuring the percentage of qsearch nodes of all nodes encountered and counted. I used the 300 WAC positions that I always use for testing and a fixed depth.
Leorik 1.0
Depth 4, QNodes 92%, 4120K NPS.
Depth 5, QNodes 93%, 7221K NPS.
Depth 6, QNodes 88%, 5905K NPS.
Depth 7, QNodes 91%, 7932K NPS.
Depth 8, QNodes 86%, 5491K NPS.
Depth 9, QNodes 90%, 7609K NPS.
Depth 10, QNodes 85%, 5249K NPS.
Leorik 1.0 with Piece encoded in 'byte' (the Version 1.3 fix)
Depth 4, QNodes 92%, 5520K NPS.
Depth 5, QNodes 93%, 11199K NPS.
Depth 6, QNodes 88%, 9778K NPS.
Depth 7, QNodes 91%, 12527K NPS.
Depth 8, QNodes 86%, 9511K NPS.
Depth 9, QNodes 90%, 12302K NPS.
Depth 10, QNodes 85%, 9262K NPS.
Leorik 1.5
Depth 5, QNodes 96%, 5343K NPS.
Depth 6, QNodes 94%, 5837K NPS.
Depth 7, QNodes 93%, 6735K NPS.
Depth 8, QNodes 92%, 7048K NPS.
Depth 9, QNodes 92%, 7036K NPS.
Depth 10, QNodes 91%, 7034K NPS.
Depth 11, QNodes 90%, 6822K NPS.
Depth 12, QNodes 89%, 6716K NPS.
Depth 13, QNodes 88%, 6463K NPS.
Depth 14, QNodes 87%, 6366K NPS.
Depth 15, QNodes 87%, 6136K NPS.
Depth 16, QNodes 86%, 6170K NPS.
For me the measurements seem to make perfect sense!
And by all means if you believe my reported NPS are too high you are welcome to critically review the
code of my search. There's no hidden modifier like certain other engines use

and to the best of my knowledge I count as conservatively as possible. While the engine is not open source (yet) the source code is on github in a public repo specifically because I want to be 100% transparent in what Leorik does. If there's anything wrong, counted twice or otherwise fishy let me know and I'll fix the bug asap.