日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
性能優(yōu)化小技巧-消除低效循環(huán),讓你的程序快到飛起

在分享這些性能優(yōu)化技巧之前,需要說明以下幾點:

  • 不要過早優(yōu)化性能
  • 現(xiàn)代編譯器的優(yōu)化能力很強大
  • 80%的性能問題集中于20%的代碼中

但是由于編譯器的優(yōu)化非常小心,它必須確保優(yōu)化前后執(zhí)行的效果是保持一致的,因此有些時候它會變得保守,并不能幫你優(yōu)化太多。

本文所需要的是在平常不需要花費太多力氣,養(yǎng)成習(xí)慣,并且對程序性能有好處的小技巧。

示例程序

為了說明本文所提到的技巧效果,先看一個示例程序,程序的目的非常簡單,就是將字符串中的小寫字母轉(zhuǎn)換為大寫),以下是完整可編譯運行代碼:

 
 
 
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #define MAX_LEN  1024*1024
  8. void printCostTime(struct timeval *start,struct timeval *end)
  9. {
  10.     if(NULL == start || NULL == end)
  11.     {
  12.         return;
  13.     }
  14.     long cost = (end->tv_sec - start->tv_sec) * 1000 + (end->tv_usec - start->tv_usec)/1000;
  15.     printf("cost time: %ld ms\n",cost);
  16. }
  17. int main(void)
  18. {
  19.     srand(time(NULL));
  20.     int min = 'a';
  21.     int max = 'z';
  22.     char *str = malloc(MAX_LEN);
  23.     //申請失敗則退出
  24.     if(NULL == str)
  25.     {
  26.         printf("failed\n");
  27.         return -1;
  28.     }
  29.     unsigned int i = 0;
  30.     while(i < MAX_LEN)//生成隨機數(shù)
  31.     {
  32.         str[i] = ( rand() % ( max - min ) ) + min;
  33.         i++;
  34.     }
  35.     str[MAX_LEN - 1] = 0; 
  36.     //統(tǒng)計時間
  37.     struct timeval start,end;
  38.     gettimeofday(&start,NULL);
  39.     for(i = 0;i < strlen(str) ;i++)
  40.     {
  41.         str[i]  = toupper( str[i] );
  42.     }
  43.     gettimeofday(&end,NULL);
  44.     printCostTime(&start,&end);
  45.     free(str);
  46.     str = NULL;
  47.     return 0;
  48. }

隨機數(shù)的生成可參考《隨機數(shù)生成的方法》。我們主要關(guān)注下面的部分:

 
 
 
  1. for(i = 0;i < strlen(str) ;i++)
  2. {
  3.     str[i]  = toupper( str[i] );
  4. }

很簡單,對不對?

運行看看時間:

 
 
 
  1. $ gcc - -o loop loop.c
  2. $ ./loop
  3. cost time: 42103 ms

總共花了42秒多!(機器處理能力不同運行結(jié)果將會有較大差異)

消除低效循環(huán)

終于來到了我們的優(yōu)化環(huán)節(jié),我們觀察代碼其實很容易發(fā)現(xiàn),每次循環(huán)的時候都會執(zhí)行一次strlen計算字符串的長度,而這個計算具有以下特點

每次結(jié)果一致,屬于重復(fù)計算

strlen時間復(fù)雜度為O(N),也就是說,字符串越長,它需要的時間也就越多

一般情況下的使用是沒有太大問題的,但是問題在于,如果是在一個多次循環(huán)中,它能極大的影響效率。

到這里,優(yōu)化方法想必你也清楚了,那就是將計算結(jié)果不會改變的計算移到循環(huán)外。代碼如下:

 
 
 
  1. unsigned int len = strlen(str);
  2. for(i = 0;i < len ;i++)
  3. {
  4.     str[i]  = toupper( str[i] );
  5. }

那么再次運行的結(jié)果如何呢?

 
 
 
  1. $ gcc -O0 -o loop loop.c
  2. $ ./loop
  3. cost time: 4 ms

看到?jīng)]有,4ms,將近一萬的性能提升!而這個數(shù)值將會隨著字符串長度的增長進一步擴大。驚不驚喜,意不意外?

總結(jié)

實際上,本文的例子是比較極端的,然后實際中就可能隱藏著很多類似的代碼:

  • 在循環(huán)中計算,但是每次結(jié)果都一樣
  • 并且該計算的復(fù)雜度不是O(1)

對于這類代碼,在不絕對影響可讀性的情況下,完全可以將其移到循環(huán)外。

思考

如果是C++的string,循環(huán)時通過str.length()獲取長度,會如此影響性能嗎?為什么?


本文標題:性能優(yōu)化小技巧-消除低效循環(huán),讓你的程序快到飛起
本文來源:http://www.5511xx.com/article/ccicoge.html