若是說以前的優化部分,數據變量和全局局部變量已經讓人頭大,那接下來的部分確定會讓各位感覺到迎面而來的清新氣息。緩存
若是可能,咱們應該使用結構體的引用做爲參數,也就是結構體的指針,不然,整個結構體就會被壓入堆棧,而後傳遞,這會下降速度。程序適用值傳遞可能須要幾K字節,而一個簡單的指針也能夠達到一樣的目的,只須要幾個字節就能夠了。 若是在函數內部不會改變結構體的內容,那麼就應該將參數聲明爲const型的指針。舉個例子:函數
void print_data_of_a_structure (const Thestruct *data_pointer) { ...printf contents of the structure... }
這個例子代碼告知編譯器在函數內部不會改變外部結構體的內容,訪問他們的時候,不須要重讀。還能夠確保編譯器捕捉任何修改這個只讀結構體的代碼,給結構體以額外的保護。優化
指針鏈常常被用來訪問結構體的信息,好比,下面的這段常見的代碼:lua
typedef struct { int x, y, z; } Point3; typedef struct { Point3 *pos, *direction; } Object; void InitPos1(Object *p) { p->pos->x = 0; p->pos->y = 0; p->pos->z = 0; }
代碼中,處理器在每次賦值操做的時候都要從新裝載p->pos,由於編譯器不知道p->pos->x不是p->pos的別名。更好的辦法是將p->pos緩存成一個局部變量,以下:spa
void InitPos2(Object *p) { Point3 *pos = p->pos; pos->x = 0; pos->y = 0; pos->z = 0; }
另外一個可能的方法是將Point3結構體包含在Object結構體中,徹底避免指針的使用。指針
條件執行主要用在if語句中,同時也會用到由關係運算(<,==,>等)或bool運算(&&, !等)組成的複雜的表達式。儘量的保持if和else語句的簡單是有好處的,這樣才能很好的條件化。關係表達式應該被分紅包含類似條件的若干塊。 下面的例子演示了編譯器如何使用條件執行:code
int g(int a, int b, int c, int d) { if(a > 0 && b > 0 && c < 0 && d < 0) //分組化的條件被捆綁在一塊兒 return a + b + c + d; return -1; }
條件被分組,便以其可以條件化他們。get
有一種常見的boolean表達式被用來檢查是否一個變量取值在某個特定的範圍內,比方說,檢查一個點是否在一個窗口內。編譯器
bool PointInRectangelArea (Point p, Rectangle *r) { return (p.x >= r->xmin && p.x < r->xmax && p.y >= r->ymin && p.y < r->ymax); }
這裏還有一個更快的方法:把(x >= min && x < max) 轉換成 (unsigned)(x-min) < (max-min). 尤爲是min爲0時,更爲有效。下面是優化後的代碼:數學
bool PointInRectangelArea (Point p, Rectangle *r) { return ((unsigned) (p.x - r->xmin) < r->xmax && (unsigned) (p.y - r->ymin) < r->ymax); }
Boolean表達式&與零的比較 / Boolean Expressions & Compares with zero 在比較(CMP)指令後,相應的處理器標誌位就會被設置。這些標誌位也能夠被其餘的指令設置,諸如MOV, ADD, AND, MUL, 也就是基本的數學和邏輯運算指令(數據處理指令)。
假如一條數據處理指令要設置這些標誌位,那麼N和Z標誌位的設置方法跟把數字和零比較的設置方法是同樣的。N標誌位表示結果是否是負數,Z標誌位表示結果是否是零。
在C語言中,處理器中的N和Z標誌位對應的有符號數的關係運算符是x < 0, x >= 0, x == 0, x != 0,無符號數對應的是x == 0, x != 0 (or x > 0)。
C語言中,每用到一個關係運算符,編譯器就會產生一個比較指令。若是關係運算符是上面的其中一個,在數據處理指令緊跟比較指令的狀況下,編譯器就會將比較指令優化掉。好比:
int aFunction(int x, int y) { if (x + y < 0) return 1; else return 0; }
這樣作,會在關鍵循環中節省比較指令,使代碼長度減小,效率增長。C語言中沒有借位(carry)標誌位和溢出(overflow)標誌位的概念,因此若是不使用內嵌彙編語言,要訪問C和V標誌位是不可能的。儘管如此,編譯器支持借位標誌位(無符號數溢出),比方說:
int sum(int x, int y) { int res; res = x + y; if ((unsigned) res < (unsigned) x) // carry set? // res++; return res; }
在相似與這樣的 if(a>10 && b=4) 語句中, 確保AND表達式的第一部分最有可能爲false, 結果第二部分極有可能不被執行.
用switch() 代替if...else...,在條件選擇比較多的狀況下,能夠用if…else…else…,像這樣:
if( val == 1) dostuff1(); else if (val == 2) dostuff2(); else if (val == 3) dostuff3();
使用switch能夠更快:
switch( val ) { case 1: dostuff1(); break; case 2: dostuff2(); break; case 3: dostuff3(); break; }
在if語句中,即便是最後一個條件成立,也要先判斷全部前面的條件是否成立。Switch語句可以去除這些額外的工做。若是你不得不使用if…else,那就把最可能的成立的條件放在前面。
把判斷條件作成二進制的風格,好比,不要使用下面的列表:
if(a == 1) { } else if(a == 2) { } else if(a == 3) { } else if(a == 4) { } else if(a == 5) { } else if(a == 6) { } else if(a == 7) { } else if(a == 8) { } }
而採用:
if(a <= 4) { if(a == 1) { } else if(a == 2) { } else if(a == 3) { } else if(a == 4) { } } else { if(a == 5) { } else if(a == 6) { } else if(a == 7) { } else if(a == 8) { } }
甚至:
if(a <= 4) { if(a <= 2) { if(a == 1) { /* a is 1 */ } else { /* a must be 2 */ } } else { if(a == 3) { /* a is 3 */ } else { /* a must be 4 */ } } } else { if(a <= 6) { if(a == 5) { /* a is 5 */ } else { /* a must be 6 */ } } else { if(a == 7) { /* a is 7 */ } else { /* a must be 8 */ } } }
慢速、低效:
c = getch(); switch(c){ case 'A': { do something; break; } case 'H': { do something; break; } case 'Z': { do something; break; } }
快速、高效:
c = getch(); switch(c) { case 0: { do something; break; } case 1: { do something; break; } case 2: { do something; break; } }
以上是兩個case語句之間的比較
惰性評估和二分分解是小編內心揮不去的痛啊!!不要放棄,共同進步,還請持續關注更新,更多幹貨和資料請直接聯繫我,也能夠加羣710520381,邀請碼:柳貓,歡迎你們共同討論