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ステートメントの代わりに三項演算子を使用できます。

ただし、生成されたアセンブリコードとその効率は、1つのループ内で同じ1つの条件付きがN回実行されている限り、見た目がいかにクールであっても、おそらく変わらないので、コードがどれほど簡潔であるかではなく、アルゴリズムに注目してください。

于 2012-10-27T21:18:07.517 に答える
4

「行数」は、伝統的にコードの判断が下手です。1行に詰め込みすぎると、判読できなくなります。

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 に答える