0

编辑:我理解混乱。但正如@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

4 回答 4

4

优化和编写最少的代码是不同的。

在 C 中,如果您只想压缩代码,可以使用三元运算符而不是 if 语句。

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

于 2012-10-27T21:18:07.517 回答
4

“行数”传统上是对代码的不良判断,如果你在一行中塞进太多,它就会变得不可读。

for(i = 0; i < 10; i++)
    printf("%s %d ", i ? "|" : "", rand() % 300);
于 2012-10-27T21:18:15.627 回答
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

换句话说,通过更改循环,它允许编译器展开循环,这应该是一个相当大的性能提升,如果不进行更改,您将无法获得。所以不要让人们对你大便。自己检查一下组装变成了什么,并不是所有的手动优化都是浪费时间。而且,当然,测试测试测试。

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

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

于 2012-10-27T21:44:32.137 回答
2

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

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

int i = 0;
for (srand(time(NULL)); i < 10; printf("%d %s ", rand() % 300, (i++ < 9 ? "|" : "")));
于 2012-10-27T21:18:48.117 回答