Suggestion to improve the do ... while loop structure

Pages: 12
We want to share this suggestion with you to improve the do ... while loop structure.

Best regards,

http://ncomputers.org/content/code.php?src=suggestions/do%20while.cpp

Sometimes the use of jumps is necessary to avoid the execution of some instructions.

For example: A loop requires auxiliary variables, which change each cycle, but after the last one, they must either remain unchanged or it is useless to change them.

This is the case of the seed, warp and swap loops of one of our n queens problem code.

To avoid the use of jumps on these cases, we are suggesting the following improvement to the do ... while loop structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main(){
    unsigned int loop1=0;
    unsigned int loop2;
    unsigned int result=0;
    unsigned int auxiliary1=1,auxiliary2=2,auxiliary3=3;
    while(loop1++<1000000000){
        /*
         * Allow initializers (extra improvement)
         */
        do(loop2=0){
            result+=auxiliary1;
            result-=auxiliary2;
            result*=auxiliary3;
        }while(++loop2<10){
            /*
             * Statements that will happen after the execution of each cycle
             * and only if there is a next cycle.
             */
            auxiliary1+=auxiliary3;
            auxiliary2*=auxiliary1;
            auxiliary3-=auxiliary2;
        }
    }
    return 0;
} 
Last edited on
Really?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(){
    unsigned int loop1=0;
    unsigned int result=0;
    unsigned int auxiliary1=1,auxiliary2=2,auxiliary3=3;
    while(loop1++<1000000000)
    {
        unsigned int loop2 = 0;
        auto do_work = [&]()
        {
            result+=auxiliary1;
            result-=auxiliary2;
            result*=auxiliary3;
            return ++loop2 < 10 ;            
        };

        while (do_work())
        {
            auxiliary1+=auxiliary3;
            auxiliary2*=auxiliary1;
            auxiliary3-=auxiliary2;
        }
    } 
}
Or in plain C:
1
2
3
4
5
6
7
8
9
10
while (1){
	result+=auxiliary1;
	result-=auxiliary2;
	result*=auxiliary3;
	if (!(++loop2 < 10))
		break;
	auxiliary1+=auxiliary3;
	auxiliary2*=auxiliary1;
	auxiliary3-=auxiliary2;
}
I like your answers.

Cire
, I like what you are purposing. It is also possible to use the comma operator:

 
while((var1++,var2--,var3*=var2,++iterator<10));


When a code has more than 15 loops of this type, to use a function for each loop can require more mental effort to read it: Search the functions, memorize what they do, etc. (Lambda expressions are not always supported by the compiler).

To inject the statements using the comma operator can make it more unreadable.

We are suggesting this improvement to make these loops easier to write and easier to read. What do you think about it?


Helios: I like what you are purposing too.

One of the reasons, why we suggest this improvement is to avoid the usage of if-statements inside a loop. We develop optimization codes, these codes can require a whole week or month to find the better solution to a problem. They make billions of iterations. An if-statement inside these loops can represent in time a whole day, which can represent in money a lot of money. May I ask you something? Is the break instruction a jump?

We recognize, that it would be usfeul to explain better what we publish. In this case: The reasons, why we are suggesting this improvement.

Thank you very much for your comments and your answers.

Best regards,

http://ncomputers.org
Last edited on
ncomputersorg wrote:
...(Lambda expressions are not always supported by the compiler)...
...We are suggesting this improvement to make these loops easier to write and easier to read...


Let me see if I've got this straight: You say the lambda solution is not desirable because not all compiler's support them, so you propose a solution that would require a change in the standard that will never be supported by as many compilers as those that support lambda expressions?

And, you want to know what I think about that? ;)
The loop you're proposing is simply a disguised if (!x) break. A hypothetical compiler would generate identical machine code from your code and my code.

If you want to eliminate the branch to optimize pipeline usage, you need to restructure your code to minimize cyclomatic complexity. For example,
1
2
3
4
5
6
7
8
9
10
11
auto last_result = result;
while (++loop2 < 10){
	last_result = result;
	result+=auxiliary1;
	result-=auxiliary2;
	result*=auxiliary3;
	auxiliary1+=auxiliary3;
	auxiliary2*=auxiliary1;
	auxiliary3-=auxiliary2;
}
result = last_result;
This particular loop can be further optimized by unrolling it, since it loops a small constant number of times. Template metaprogramming can be used to write maintainable auto-unrolling loops.

Inventing new syntax is not a form of optimization.
Last edited on
Yes, we are suggesting a change for the next revision of the C++ Programming Language, which is expected to happen after 2020

I didn't want to say, that lambda solutions are not desirable. I think, that when lambda solution is not possible, it would be necessary to write a function outside the scope, where the loop is located. That will require more mental effort to read and understand the loop, due to the distance (amount of lines) between the while statement and the function.

Your solution is a good one: for the actual C++ Standard. We talk about the future of the C++ standard programming language. We desire an easier way to write these loops.

Thank you for your comments :D

Best regards,

http://ncomputers.org
See my reply, in case you missed it.
Yes, we are suggesting a change for the next revision of the C++ Programming Language, which is expected to happen after 2020

Just pulling a date out of your hat?
https://isocpp.org/std/status


I didn't want to say, that lambda solutions are not desirable. I think, that when lambda solution is not possible, it would be necessary to write a function outside the scope, where the loop is located.

The only place the lambda solution is not possible is in compilers which do not conform to the standard.


Your solution is a good one: for the actual C++ Standard. We talk about the future of the C++ standard programming language. We desire an easier way to write these loops.

Adding this to a future standard is going to help non-compliant compilers how?
Helios and Cire:

Thank you very much for your comments :D

When I read what you wrote and understand your point of view, I agree partially or almost totally with you.

Cire: I read the link you shared with us. I am strong obsessed with the opinion of someone, with I identify myself and who thinks, that the next major revision of the C++ programming language will happen after 2020.

I know and understand, that there are other solutions and other forms to avoid the use of jumps (goto, break, continue, function, etc.) This is only a suggestion, which can be a good suggestion or a bad suggestion.

I invite you to observe patiently the development of the programming languages.

If this suggestion is a good one, one day the programming languages will allow this syntax or a similar.

If it is a bad one, nobody will use it.

You gave us part of your time, you commented this suggestion and it is something great for us.

I hope, that I can give a tiny grain of sand to improve something, that I like: Computers and programming!

Best regards,

http://ncomputers.org
Last edited on
It is also possible to use a trick:

1
2
3
4
5
for(;;){
   //Block A
   if(condition)break;
   //Block B
}


http://ncomputers.org
Last edited on
One would think I didn't say that three weeks ago.
Helios,

Yes, I recognize, that you said it indirectly three weeks ago.

http://ncomputers.org
If you continue to advertise your website in each post I will begin marking your posts as spam.
Ok, it was intended as salutation.
Helios:

I've read today the generated code of:

1
2
3
4
5
while(1){
    //Block A
    if(condition)break;
    //Block B
}

I want to recognize that, what you suggested is a better way to write those loops than:

1
2
3
4
5
for(;;){
    //Block A
    if(condition)break;
    //Block B
}

I thought that without optimizers, the compiler will generate an extra cmp instruction.

Thank you very much!

PF, ncomputers
I want to recognize that, what you suggested is a better way to write those loops than:

There is no "better" here. It's entirely subjective.
There is no "better" here. It's entirely subjective.
Ok... Depending on the point of view, it could be considered a better option :D
Oh Cire!

I was looking for you!

I want to personally thank you for all your comments and your help!

You helped me a lot!

PF, ncomputers
Pages: 12