The number of instructions that you write in the source code is not strictly related to the number of machine instructions that the compiler generates.
Most compilers are more intelligent, and in your second example, it can generate code like:
operation(); operation(); operation(); operation(); operation();
automatically because they detect that the cycle will always be repeated 5 times.
Also, if you perform profiling-oriented optimization, and the compiler sees that the loop has a tiny body and a very high repeat counter, it can expand it even for the total number of iterations with code like:
while (count >= 5) { operation(); operation(); operation(); operation(); operation(); count -= 5; } while (count > 0) { operation(); count--; }
This will result in a large count about one fifth of the tests compared to the naive version.
If it's worth it or not, this is something that only profiling can describe.
One thing you can do if you know for sure that the code must be executed at least once is to write
do { operation(); } while (--count);
instead
while (count--) { operation(); }
The possibility that count==0 somewhat annoying to the processors, because in the code generated by most compilers, an additional JMP is added forward:
jmp test loop: ...operation... test: ...do the test... jne loop
machine code for version do { ... } while - it's just
loop: ... opertion ... ... do the test... jne loop