Why C++ instead of C#?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
lithander
Posts: 880
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Re: Why C++ instead of C#?

Post by lithander »

klx wrote: Mon Sep 20, 2021 10:55 pm Anyway on my machine I get the following results, using the optimized v1.4 C# version:

Code: Select all

C: 20959 ms
C#: 33845 ms (1.61x slower)
Java: 37483 ms (1.79x slower)
Is Java also using the v1.4 code? Does it support the same hardware intrinsic? But in any case that's not bad speed at all...

Meanwhile I updated both version to print the same total stats to make it easier comparable and less (human)error prone:

Code: Select all

QBB Perft in C
1740 ms, 68425K NPS
2525 ms, 76709K NPS
2771 ms, 64465K NPS
9793 ms, 72096K NPS
2 ms, 26696K NPS
2139 ms, 76706K NPS

Total: 1361558651 Nodes, 18970 ms, 71774K NPS

Code: Select all

QBB Perft in C#
OK! 2853ms, 41729K NPS
OK! 3766ms, 51418K NPS
OK! 4176ms, 42770K NPS
OK! 14369ms, 49133K NPS
OK! 1ms, 47569K NPS
OK! 3228ms, 50826K NPS

Total: 1361558651 Nodes, 28395ms, 47949K NPS
Last edited by lithander on Tue Sep 21, 2021 12:40 am, edited 1 time in total.
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess
User avatar
mvanthoor
Posts: 1784
Joined: Wed Jul 03, 2019 4:42 pm
Location: Netherlands
Full name: Marcel Vanthoor

Re: Why C++ instead of C#?

Post by mvanthoor »

klx wrote: Mon Sep 20, 2021 11:48 pm To prove this, I just replaced all the #defines with inline functions in the C file, and the performance is identical.
Yes, the performance is identical _if_ the compiler decides to inline the function. (Macro's are always replaced / inlined into a single expression.) I don't know for sure about C / C++ if "inline" actually _always_ inlines a function, but in Rust, it doesn't. If Rust decides that inlining the function slows down or bloats the program (beyond some threshold I don't know), then it doesn't inline, even if you use an [inline] directive.
Author of Rustic, an engine written in Rust.
Releases | Code | Docs | Progress | CCRL
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Why C++ instead of C#?

Post by R. Tomasi »

tcusr wrote: Mon Sep 20, 2021 11:51 pm
R. Tomasi wrote: Mon Sep 20, 2021 11:25 pm
mvanthoor wrote: Mon Sep 20, 2021 11:10 pm There is still a difference. If you inline a function, the compiler pastes the code of the called function into the caller, but the code of the called function still gets executed at every run of the encompassing function. When you use a macro, the compiler not only inlines it, but also resolves it to a single value if at all possible.
Problem is, with modern compilers there is no guarantee an inline function will be inlined at all. The compiler will only consider it as a hint and then do hat it thinks is best. If the macro resolves to a compile-time constant, the corresponding function (in C++) would be a constexpr function, which may get evaluated at compile time.
the inline keywords in C and C++ has different meanings.
in C++ is basically 'don't complain if you see multiple definitions of ...', meanwhile in C it is a hint, like you said.
usually only large functions are not inlined but if you really want to you can use GCC's attributes. a rule of thumb is to declare a function inline if it's less than 10 LOC.
Yeah. Btw, an equivalent attribute for MSVC is __forceinline. The compiler will complain though, if you use it on recursive functions (for obvious reasons).
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Why C++ instead of C#?

Post by R. Tomasi »

mvanthoor wrote: Tue Sep 21, 2021 12:34 am
klx wrote: Mon Sep 20, 2021 11:48 pm To prove this, I just replaced all the #defines with inline functions in the C file, and the performance is identical.
Yes, the performance is identical _if_ the compiler decides to inline the function. (Macro's are always replaced / inlined into a single expression.) I don't know for sure about C / C++ if "inline" actually _always_ inlines a function, but in Rust, it doesn't. If Rust decides that inlining the function slows down or bloats the program (beyond some threshold I don't know), then it doesn't inline, even if you use an [inline] directive.
It doesn't. As was already pointed out, in C it's a hint and in C++ its a syntactic thing: it means you can have it in a header and the compiler will not complain if it sees it multiple times. Methods defined inside class definitions are implicitely inline in that sense.
Chessnut1071
Posts: 313
Joined: Tue Aug 03, 2021 2:41 pm
Full name: Bill Beame

Re: Why C++ instead of C#?

Post by Chessnut1071 »

R. Tomasi wrote: Thu Sep 02, 2021 5:06 pm
Mergi wrote: Thu Sep 02, 2021 1:14 am
You may also find this in C++. The fastest possible code is not always idiomatic or pretty.
C++ should suffer from this way less than most other languages though, as it's goal already is to be as efficient as possible. If you stick to the STL and "proper" C++ code, the performance gains from using some dirty tricks or trying to avoid certain constructs should be minimal.
I second that. In my experience modern compilers are very very good at optimizing and the more you stick to recommended design patterns, the better it will understand your code and do it's job. Granted, on rare occasions you can do "ugly" code that performs better than "pretty" code, but usually that is then tied to one particular platform and one particular compiler.

Concerning the the question of C# or C++ being the better language, i would say that both have their pros and cons. I really do love C#, and whenever the target platform allows it (you will need the .net runtime or some replacement like mono) and the problem at hands is not totally time critical. That's because in C# I am simply much more productive. It takes less time to code the same thing for me, and the .net standard library is fantastic. Obviously if you really need that last bit of performance you should go for C++, however most people would be surprised how good a well written C# program can perform. It's not worlds apart from C++ imho.
I totally roger that. You can code a lot faster in C#, then, later optimize in C++ if it improves significantly with respect to time. Faster development usually means less errors. The problem with C++ first is an time for increased development time of the the release. At least for me, it's faster to write in C# then convert to C++. Nobody's arguing that C# is faster compilewise, just developmentwise. Go C#!
klx
Posts: 179
Joined: Tue Jun 15, 2021 8:11 pm
Full name: Emanuel Torres

Re: Why C++ instead of C#?

Post by klx »

mvanthoor wrote: Tue Sep 21, 2021 12:34 am
klx wrote: Mon Sep 20, 2021 11:48 pm To prove this, I just replaced all the #defines with inline functions in the C file, and the performance is identical.
Yes, the performance is identical _if_ the compiler decides to inline the function.
Right, but if you look at the actual application, the macros we're talking about are things like this:

Code: Select all

#define ClearLSB(bb) ((bb)&((bb)-1))

#define Rooks (~Position->P0 & ~Position->P1 & Position->P2)
In practice, the compiler will inline this if you make it into functions. Again, can't speak for Rust, but I'd be very surprised if it doesn't. Even in Java this appears to be inlined (since manually inlining it doesn't change performance). So there's definitely no need to complicate things if you wanted to port this to Rust.
[Moderation warning] This signature violated the rule against commercial exhortations.
klx
Posts: 179
Joined: Tue Jun 15, 2021 8:11 pm
Full name: Emanuel Torres

Re: Why C++ instead of C#?

Post by klx »

lithander wrote: Tue Sep 21, 2021 12:33 am
klx wrote: Mon Sep 20, 2021 10:55 pm Anyway on my machine I get the following results, using the optimized v1.4 C# version:

Code: Select all

C: 20959 ms
C#: 33845 ms (1.61x slower)
Java: 37483 ms (1.79x slower)
Is Java also using the v1.4 code? Does it support the same hardware intrinsic? But in any case that's not bad speed at all...
No, it was based on the original. I just copied the v1.4 changes to Java, and reran all tests with a slightly cooler CPU than last time (I don't have a fixed clock speed, so the results are not very stable). The new results are:

Code: Select all

C: 19600 ms
Java: 32048 ms (1.64x)
C#: 32858 ms (1.68x)
In other words, as of now, the Java version is slightly faster than C#.

But, just to make sure, how do you build and run your C# version for maximum performance? My version seems to be much slower than yours, even though our C versions are close to the same speed.
[Moderation warning] This signature violated the rule against commercial exhortations.
User avatar
lithander
Posts: 880
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Re: Why C++ instead of C#?

Post by lithander »

klx wrote: Tue Sep 21, 2021 10:27 am how do you build and run your C# version for maximum performance? My version seems to be much slower than yours, even though our C versions are close to the same speed.
I target .NET 5 and use Visual Studio to publish the release. (So I don't run my benchmarks out of the IDE)

Code: Select all

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net5.0\publish\</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <TargetFramework>net5.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>false</SelfContained>
    <PublishSingleFile>False</PublishSingleFile>
    <PublishReadyToRun>False</PublishReadyToRun>
  </PropertyGroup>
</Project>
Ahead of time compilation vs JIT doesn't make a difference in my tests.
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess
klx
Posts: 179
Joined: Tue Jun 15, 2021 8:11 pm
Full name: Emanuel Torres

Re: Why C++ instead of C#?

Post by klx »

lithander wrote: Tue Sep 21, 2021 12:27 pm I target .NET 5 and use Visual Studio to publish the release. (So I don't run my benchmarks out of the IDE)
Ok, hmm, perhaps it's faster on Windows. I target .NET 6, and run with:

Code: Select all

dotnet build -c Release
dotnet bin/Release/net6.0/QbbCs.dll
[Moderation warning] This signature violated the rule against commercial exhortations.
R. Tomasi
Posts: 307
Joined: Wed Sep 01, 2021 4:08 pm
Location: Germany
Full name: Roland Tomasi

Re: Why C++ instead of C#?

Post by R. Tomasi »

klx wrote: Tue Sep 21, 2021 3:20 pm
lithander wrote: Tue Sep 21, 2021 12:27 pm I target .NET 5 and use Visual Studio to publish the release. (So I don't run my benchmarks out of the IDE)
Ok, hmm, perhaps it's faster on Windows. I target .NET 6, and run with:

Code: Select all

dotnet build -c Release
dotnet bin/Release/net6.0/QbbCs.dll
You're running it against mono? That's most certainly slower than the MS implementation.