Richard Allbert wrote:
But I think Richard might be in a somewhat different performance place, where he does need to analyse the performance of his C# code now.
certainly am! I'm hoping to get some time on this tomorrow, I'll post the speed to d5 from the start position, and some more detail of the structure.
[/quote]
I think your problem is not how to optimize the SquareIsAttacked function, but why do you need it in the first place ?
Here's what I do in my program DoubleCheck (written in C). It should give you some ideas:
* calculate a bitboard dcheckers, representing the potential discovery checkers (pieces that can give discovered check if they move out of the "ray")
* calculate a bitboard pinned, representing the pinned pieces (pieces that can give self check if they move out of the "ray")
rays are of course bitboards calculated once at initialization, so testing for self check or discovered check is very fast.
Whenever I calculate something like this, I only do it after I play a move, and store the result in a board stack. When I undo a move, I just read the value from the stack. This divides by 2 the time spent on these calculations, of course.
I also do the following things in my code, that are useful for the search but not for perft
* dynamically calculate piece on square tables
* discovery checker bitboard
* a check flag which is a property of my move object (rather struct). I have the following: check=0 (no check) check=1 (direct check) check=2 (discovered check). This is very useful in the search: checks are typically extended, and when a check is a discovered check, I never trust the SEE which has some implications in the search and especially the qsearch.
But even with those things (useless for pure perft), I still reach over 30 million nodes per seconds or so... on a laptop...
And there's no cheat (no perft hash table, or perft approximations).
You'll certainly be able to improve the performance of your code by a fair amount, but at some point you'll reach a stage where:
1/ you realize that the same code in C# is much slower than C
2/ you have to be careful never to use any of the nice object oriented crap of C#, make sure you never trust anything that the compiler does behind your back (like exceptions, memory allocation, garbage collection)
3/ your code will become C code really, but with C# syntax. and you'll spend more time and effort coding in C# than in plain C, because of 2/
I don't think C# is a good choice for a chess engine. If you were writing a chess GUI for example, then C# would be much easier than plain C, and performance wouldn't be important, so C# would be a better choice than C.
All I can say is: rewrite it in plain C while it's not too late... And the same applies to Java, which IMO is total and utter crap