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.
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).
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.
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 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:
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.
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:
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.
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)
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:
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: