C - 有没有办法用更少的代码写这个?

时间:2012-10-27 21:14:24

标签: c

编辑:我理解这种困惑。但我并不想在这里进行优化,正如@sergio所说,我无法想出更好的词汇。

-

我已经用JavaScript和PHP编写代码很长一段时间了,我觉得有时很难在C中优化我的代码。

优化的意思是用更少的代码编写程序。这是一个例子:

int i;

srand(time(NULL));

for(i = 0; i < 10; i++){
    printf(" %d ", rand() % 300);
    if(i < 10 - 1){
        printf("|");
    }
}
在Javascript中我会以这种方式写它:

var html = ''
for(var i = 0; i < 10; i++){
    html += ' '+Math.floor(Math.random() * 100)+' '+( i == 9 ? '|' : '' )
}

C的不同之处在于我必须在另一行中执行If,并且无法对字符串进行内联操作。我希望你明白我的观点。

那你怎么写我的代码?

谢谢。

4 个答案:

答案 0 :(得分:4)

优化和编写最小代码不同

在C中,如果您只想压缩代码,则可以使用 ternary operator 而不是if语句。

生成的汇编代码及其效率可能不会改变只要您在1次循环中运行N次时具有相同的1个条件,无论它看起来多么酷,所以专注于算法,而不是代码的简洁程度。

答案 1 :(得分:4)

“行数”传统上是一个糟糕的代码判断,如果你把一行过多塞进它就不可读了。

for(i = 0; i < 10; i++)
    printf("%s %d ", i ? "|" : "", rand() % 300);

答案 2 :(得分:3)

这个回答是对Murilo Vasconcelos的回应:

使用http://gcc.godbolt.org/跟进。

#include <stdio.h>
#include <ctime>
#include <cstdlib>

int main() {
  int i;
  srand(time(NULL));
  for(i=0; i< 10; i++){
      printf(" %d ", rand() % 300);
      if(i < 10 - 1){
          printf("|");
      }
  }
}

使用g ++ - 4.8生成以下程序集:

.LC0:
    .string " %d "
main:
    pushq   %rbp
    xorl    %edi, %edi
    movl    $458129845, %ebp
    pushq   %rbx
    xorl    %ebx, %ebx
    subq    $8, %rsp
    call    time
    movl    %eax, %edi
    call    srand
    call    rand
    movl    $458129845, %edx
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
.L2:
    movl    $124, %edi
    addl    $1, %ebx
    call    putchar
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebp
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    cmpl    $9, %ebx
    jne .L2
    addq    $8, %rsp
    xorl    %eax, %eax
    popq    %rbx
    popq    %rbp
    ret

另一方面,这段代码:

#include <stdio.h>
#include <ctime>
#include <cstdlib>    

int main() {
    int i;
    srand(time(NULL));

    for (i = 0; i < 9; i++) {
        printf(" %d |", rand() % 300);
    }

    printf(" %d ", rand() % 300);
}

生成此程序集:

.LC0:
    .string " %d |"
.LC1:
    .string " %d "
main:
    pushq   %rbx
    xorl    %edi, %edi
    movl    $458129845, %ebx
    call    time
    movl    %eax, %edi
    call    srand
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $5, %edx
    sarl    $31, %eax
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC0, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    call    rand
    movl    $.LC1, %edi
    movl    %eax, %esi
    imull   %ebx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $5, %edx
    subl    %eax, %edx
    xorl    %eax, %eax
    imull   $300, %edx, %edx
    subl    %edx, %esi
    call    printf
    xorl    %eax, %eax
    popq    %rbx
    ret

换句话说,通过更改循环,它允许编译器展开循环,这应该是一个相当大的性能增加,如果没有您的更改,您将无法获得。所以不要让人们便便劝你。检查装配成为什么,并非所有手动优化都是浪费时间。当然还有测试测试。

但是,当然,你不应该过早地进行优化。您应该关注您的分析器,让它告诉您您的热点是什么,以及您需要优化的位置。

首先是更好的算法 然后更好的代码。
然后更好的组装。

答案 3 :(得分:2)

编辑:OP编辑了这个问题。

如果您只想制作内联代码:

int i = 0;
for (srand(time(NULL)); i < 10; printf("%d %s ", rand() % 300, (i++ < 9 ? "|" : "")));