Declaring variables behind the loop or inside the loop? - page 11

 
Vict:

I looked it up, it turns out that no https://en.cppreference.com/w/cpp/compiler_support compiler has finished the modules, so there's nothing to see.

Still managed to use the modules via clang

// module
export module M;
export int f(int x) {
    return 2 + x;
}

// main.cc
import M;
int main() {
        for(int i = 0;  i < 1000000;  ++ i)
                f(5);
}

Compiled with optimization, the loop was not executed at all (i.e. optimization is done among: translation unit + half-connected modules, instead of only one translation unit as before). Without any LTO. std c++ candidate move entirely to modules, imho, and there will be no questions: "why so slow on this artificial example with naked loop".

 
Alexey Navoykov:

So it seems to have figured out that it allocates and deletes memory every time even in this case:


By the way, I may have given wrong results last time. It was most likely in x86 mode. Now I am testing in x64 mode and the results by C++ are much better:

1) ~ 2000 msec

2) ~ 200 ms (it is 3 times faster).

Although I also updated Studio to the latest version, it must have influenced it too since even x86 is faster now than previous tests.

Well, now C++ is not so shamefully loses to Sharp. only by 3 times approximately )

Hmm, so there's no garbage collector, what's the definition question?

I'm not talking about speed, I'm talking about memory
 
Alexey Navoykov , it turns out that constexpr string and vector were dragged into c++20. I.e. all our tests will not take a single instruction at all to serve a string, e.g. allocate memory, etc. (well, if symbols don't come from early time of course). Cool.
 
Vict:
Alexey Navoykov , it turns out that constexpr string and vector were dragged into C++20. I.e. all these tests will not take a single instruction at all for string maintenance, e.g. allocate memory, etc. (well, if symbols don't come from early time of course). Cool.

So does it require marking everything explicitly as constexpr, or will it automatically detect it?

As I see it, the problem is not in the standard, but in the compiler. Does something prevent it from cutting out unnecessary stuff now? Especially strange that the Sharp compiler optimizes normally, while the plus version from the sameMicrosoft fails. Although it seems that they should have a common base (in terms of optimization of such constructions)

 
Alexey Navoykov:

So does it require marking everything explicitly as constexpr, or will it automatically detect it?

The std is automatic, it's enough that the string gets the strings that are known at compile time. All operations (search, replace, ...) with this string will be the same at compile time (I suspect that sharp and mcl counted our examples at compile time too). The plan is to make all containers constepxr. I.e. it doesn't depend on mood of compiler any more, but guaranteed by standard, we can calculate template parameter via string parsing, for example. Here is what is interesting - it turns out that new/delete now also constexpr (for constexpr types)?

As it seems to me, the problem is not in the standard but in the compiler. Does something prevent it from cutting out unnecessary stuff? Especially strange is the fact that the Sharp compiler optimizes normally and the plus version by the same Microsoft fails, although it seems that they must have a common base (in terms of optimization of such constructs)

Plus has a disadvantage in terms of optimization possibilities - it is only within one translation unit (if we don't use LTO). Of course you can do the whole std on header files, but they don't (because of compile time ?). Sharp with modules is more advanced in this regard. But c++20 will also fix this soon with the advent of modules. Also plans to move std there (first they will debug the modules and then they will write it). But VS seems to have already done std on modules, you can try it (left the link above).

But I still insist - it is better to declare after the loop (well, if it is not a fundamental type).

 
Alexey Navoykov:

I decided to test it in C# too for the sake of curiosity. Not only the results are nearly the same in speed, but they also work much faster than C++.

Results:

Sum: 894782460, Time: 69 ms.

Sum: 894782460, Time: 56 ms

And here is an analogue in C++:

Sum: 894782460, Time: 2947 ms

Sum: 894782460, Time: 684 ms

I test it in VS 2019.All optimization is enabled .

Screw such a C++ program).

p.s. Results in C# vary pleasantly from test to test, but on the average both variants are equally fast.

Hint: in sharpe string is base type, in pluses it is a class written in pluses. In Sharpe variant string assignment is done once, in pluses - 10e6 times. In the end, pluses are faster, but you need to be smart when writing code, not make a humpback like the Indians in Boeing.
 
SeriousRacoon:
Hint: In sharpe, string is base type, in pluses it is a class written in pluses. In Sharpe variant string assignment is done once, in pluses - 10e6 times. The result is that pluses are faster, but you need to turn on your brain when writing code instead of making a hunchback like the Indians in Boeing.
No, that's not what it's all about. I simply forgot that string there is a class and it is the reference which is assigned, not the object itself. So, the comparison is incorrect in this form
 

By the way, speaking of optimization. Would you like the compiler to optimise something here?

mutex mtx;

void thread_0() {
        while (true) {
                do_task_0();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_1();
                }
                do_task_2();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_3();
                }
                do_task_4();
        {
}
void thread_1() {
        while (true) {
                do_task_5();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_6();
                }
                do_task_7();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_8();
                }
                do_task_9();
        {
}
 
Alexey Navoykov:
No, the point is quite different there. I've just forgotten that string is a class there and it's a reference that's assigned, not the object itself. So, the comparison is incorrect in this form
Where is reference (pointer) assigned? In the plus class string? What do you mean, buffer selection and copying take place there.
 
SeriousRacoon:
Where is the reference (pointer) assigned? In the plus class string? What do you mean, it's buffer selection and copying.

he's talking about sharp