Would there be a efficiency loss to use "n--"

If I use ordinary method, would it be running faster if repeat a lot of times.

1
2
while(n-->0)
p[n]=c;


1
2
3
4
while(n>0){
n=n-1;
p[n]=c;
}
It's very unlikely to make any difference. I'd expect an optimizing compiler to reduce them to the same logical work, anyway.
closed account (Dy7SLyTq)
there isnt going to be a difference between where the counter decrement is placed, because even if you do the top one it will become the second one (in assembly you cant do the top one; its one directive per line). however i think there is a difference between INC memory and ADD memory, 1
It depends on the types of n, p, and c and on what their respective operators do.

For very simple types, such as int, the two pieces of code are exactly the same unless you have a grossly un-optimizing compiler.. let's see what I have:

1
2
3
4
5
6
7
void f1(int* p, int n, int c)
{
    while(n-->0)
        p[n]=c;
}
void f2(int* p, int n, int c)
{
    while(n>0){
        n=n-1;
        p[n]=c;
    }
}


loop only part of the produced assembly code

gcc/intel
1
2
3
4
5
.L4:
        movl    %edx, (%rcx,%rax)
        subq    $4, %rax
        cmpq    %rsi, %rax
        jne     .L4
.L9:
        movl    %edx, (%rax)
        subq    $4, %rax
        cmpq    %rcx, %rax
        jne     .L9

icc/intel
1
2
3
4
5
..B2.12:
        movdqu    %xmm0, (%rdi,%r8,4)
        addq      $4, %r8
        cmpq      %rsi, %r8
        jb        ..B2.12
..B3.12:
        movdqu    %xmm0, (%rdi,%r8,4)
        addq      $4, %r8
        cmpq      %rsi, %r8
        jb        ..B3.12

clang++/intel
1
2
3
4
5
6
7
.LBB0_3:
        movdqu  %xmm0, (%r10,%rcx,4)
        movdqu  %xmm0, -16(%r10,%rcx,4)
        addq    $-8, %rcx
        movq    %r9, %rsi
        addq    %rcx, %rsi
        jne     .LBB0_3
.LBB1_3:
        movdqu  %xmm0, (%r10,%rcx,4)
        movdqu  %xmm0, -16(%r10,%rcx,4)
        addq    $-8, %rcx
        movq    %r9, %rsi
        addq    %rcx, %rsi
        jne     .LBB1_3

gcc/sparc
1
2
3
4
5
6
.LL5:
        add     %o0, %g1, %g2
        add     %g1, -4, %g1
        cmp     %g1, %g3
        bne,pt  %icc, .LL5
        st     %o2, [%g2-4]
.LL13:
        add     %o0, %g1, %g2
        add     %g1, -4, %g1
        cmp     %g1, %g3
        bne,pt  %icc, .LL13
        st     %o2, [%g2-4]
Sun Studio 12/sparc
1
2
3
4
5
6
7
8
9
10
.L900000105:
         prefetch        [%o3-520],22
         st      %o4,[%o3]
         add     %o5,-4,%o5
         sub     %o3,16,%o3
         st      %o4,[%o3+12]
         st      %o4,[%o3+8]
         cmp     %o5,3
         bge,pt  %icc,.L900000105
         st      %o4,[%o3+4]
.L900000207:
         add     %o5,-1,%o5
         sub     %o3,4,%o3
         cmp     %o5,1
         bge,a,pt        %icc,.L900000207
         st      %o4,[%o3]

gcc/ibm
1
2
3
L..5:
        stwu 5,-4(3)
        bdnz L..5
L..12:
        stwu 5,-4(3)
        bdnz L..12

xlC/ibm
1
2
3
4
__L40:
        stw        r5,-4(r3)
        addi       r3,r3,-4
        bc         BO_dCTR_NZERO_9,CR0_LT,__L40
__L180:
        stw        r5,-4(r3)
        addi       r3,r3,-4
        bc         BO_dCTR_NZERO_9,CR0_LT,__L180


As all too often, the award for being different goes to Oracle.
closed account (Dy7SLyTq)
oracle made a front end? and how correct was i cubbi, just so i know for future reference?
@DTSCode Oracle bought Sun some time ago, which, like any hardware vendor, had a C++ compiler.. except it has more bugs (arguably) than VC6
Assembly is indeed one directive per line, but it doesn't have to be any sort of "INC" or "ADD" (case in point, IBM's bdnz is essentially "while(n-- > 0)" in one CPU instruction)
closed account (Dy7SLyTq)
i knew oracle bought sun. i didnt know that hardware companies have their own compilers. good to know. sorry about misleading :L i had been told that when i was doing stuff that could potentially be unoptimizing
though a bit ambitious to me for now, thanks a lot!
Topic archived. No new replies allowed.