2012-10-27 198 views
0

編輯:我理解混亂。但我不想在這裏優化,因爲@sergio說,我不能提出一個更好的詞。C - 有沒有辦法用較少的代碼來編寫它?

-

我一直在寫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不同的是,我必須做的。如果在其他線路,而不能採取行動內聯在字符串上。我希望你明白我的觀點。

那麼,你會如何寫我的代碼?

謝謝。

+2

C也有三元運算符。 – chris

+0

什麼是你的問題?例如,你可以通過刪除無用的'{'和'}'來縮短你的C代碼示例代碼。 –

+1

C並不完全是一種簡潔寫作的語言:) –

回答

4

「行數」傳統上是一個糟糕的代碼判斷,如果你把太多的代碼塞進一行就會變得不可讀。

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

由於這是一個打印數組的函數,因此這裏的這個方法非常清晰且非常易讀。 –

4

優化和書寫最小代碼是不同

在C中,如果只想簡化代碼,則可以使用而不是if語句。

產生的彙編代碼和它的效率。然而可能不會改變只要你有相同的條件1中1循環運行N次,不管它看起來多麼酷,所以專注於算法,而不是代碼的簡潔程度如何。

2

編輯:在OP編輯的問題。

如果你只想做一個內聯代碼:

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

你正在做編譯器會爲你做的工作。沒有有效利用你的時間。 –

+0

@DietrichEpp是的,你有一個點,除非-O0標誌被使用:P –

+0

你似乎編輯了你的答案,但我發佈了一個答案來回應你的答案。並回應Dietrich的評論。 – OmnipotentEntity

3

這個答案是響應穆裏羅洛斯:

使用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("|"); 
     } 
    } 
} 

生成以下組件使用克++ - 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 

在其它單詞,通過改變l oop它允許編譯器展開循環,這應該是一個相當大的性能提升,你沒有改變就不會得到。所以,不要讓人們流便你。檢查自己的組裝是什麼,並非所有的手優化都是浪費時間。當然,還有測試測試測試。

但是,當然,你不應該過早優化。你應該關注你的分析器,讓它告訴你你的熱點是什麼,以及你需要優化的地方。

首先是更好的算法。
然後更好的代碼。
然後更好的組裝。

+0

+1!好的測試!你使用過O2旗嗎? –

+0

順便說一句,你已經忘了第一個例子中的for循環!但是我運行了這個例子,看到的確如此,當循環內部有'if'時,循環並未展開。 –

+0

你說「應該是一個相當大的性能提升」,但你還沒有分析。我挑戰你衡量兩個版本之間甚至1%的性能差異。考慮到一個'printf'調用需要大量的分支,從最外層的循環中移除一個分支只會讓代碼難以維護,因爲對一個'printf'語句的任何修改都必須手動複製到另一個。此外,'clang'會在'-O2'時自動執行。 –

相關問題