国产chinesehd精品酒店,邱淑贞aa极毛片,国产在线色视频,玖玖爱zh综合伊人久久

網(wǎng)站首頁
手機(jī)版

優(yōu)化C代碼常用的五招!

更新時間:2022-04-03 16:11:09作者:未知

優(yōu)化C代碼常用的五招!

  在性能優(yōu)化方面永遠(yuǎn)注意80-20原則,即20%的程序消耗了80%的運行時間,因而我們要改進(jìn)效率,最主要是考慮改進(jìn)那20%的代碼。不要優(yōu)化程序中開銷不大的那80%,這是勞而無功的。

  

  第一招:以空間換時間

  

  計算機(jī)程序中最大的矛盾是空間和時間的矛盾,那么,從這個角度出發(fā)逆向思維來考慮程序的效率問題,我們就有了解決問題的第1招--以空間換時間。比如說字符串的賦值:

  

  方法A:通常的辦法

  

  #define LEN 32

  

  char string1 [LEN];

  

  memset (string1,0,LEN);

  

  strcpy (string1,"This is a example!!");

  

  方法B:

  

  const char string2[LEN] ="This is a example!";

  

  char * cp;

  

  cp = string2 ;

  

  使用的時候可以直接用指針來操作。

  

  從上面的例子可以看出,A和B的效率是不能比的。在同樣的存儲空間下,B直接使用指針就可以操作了,而A需要調(diào)用兩個字符函數(shù)才能完成。B的缺點在于靈活性沒有A好。在需要頻繁更改一個字符串內(nèi)容的時候,A具有更好的靈活性;如果采用方法B,則需要預(yù)存許多字符串,雖然占用了大量的內(nèi)存,但是獲得了程序執(zhí)行的高效率。

  

  如果系統(tǒng)的實時性要求很高,內(nèi)存還有一些,那我推薦你使用該招數(shù)。

  

  第二招: 使用宏而不是函數(shù)。

  

  這也是第一招的變招。函數(shù)和宏的區(qū)別就在于,宏占用了大量的空間,而函數(shù)占用了時間。大家要知道的是,函數(shù)調(diào)用是要使用系統(tǒng)的棧來保存數(shù)據(jù)的,如果編譯器里有棧檢查選 項,一般在函數(shù)的頭會嵌入一些匯編語句對當(dāng)前棧進(jìn)行檢查;同時,CPU也要在函數(shù)調(diào)用時保存和恢復(fù)當(dāng)前的現(xiàn)場,進(jìn)行壓棧和彈棧操作,所以,函數(shù)調(diào)用需要一 些CPU時間。 而宏不存在這個問題。宏僅僅作為預(yù)先寫好的代碼嵌入到當(dāng)前程序,不會產(chǎn)生函數(shù)調(diào)用,所以僅僅是占用了空間,在頻繁調(diào)用同一個宏的時候,該現(xiàn)象尤其突出。

  

  舉例如下:

  

  方法C:

  

  #define bwMCDR2_ADDRESS 4

  

  #define bsMCDR2_ADDRESS 17

  

  int BIT_MASK(int __bf)

  

  {

  

  return ((1U << (bw ## __bf)) - 1)<< (bs ## __bf);

  

  }

  

  void SET_BITS(int __dst,

  

  int __bf, int __val)

  

  {

  

  __dst = ((__dst) & ~(BIT_MASK(__bf))) |

  

  \

  

  (((__val) << (bs ## __bf))

  

  & (BIT_MASK(__bf))))

  

  }

  

  SET_BITS(MCDR2, MCDR2_ADDRESS,ReGISterNumber);

  

  方法D:

  

  #define bwMCDR2_ADDRESS 4

  

  #define bsMCDR2_ADDRESS 17

  

  #define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)

  

  #define BIT_MASK(__bf)

  

  (((1U << (bw ## __bf)) - 1)

  

  << (bs ## __bf))

  

  #define SET_BITS(__dst, __bf, __val)

  

  \

  

  ((__dst) = ((__dst) & ~(BIT_MASK(__bf)))

  

  | \

  

  (((__val) << (bs ## __bf))

  

  & (BIT_MASK(__bf))))

  

  SET_BITS(MCDR2, MCDR2_ADDRESS,

  

  RegisterNumber);

  

  D方法是我看到的最好的置位操作函數(shù),是arm公司源碼的一部分,在短短的三行內(nèi)實現(xiàn)了很多功能,幾乎涵蓋了所有的位操作功能。C方法是其變體,其中滋味還需大家仔細(xì)體會。

  

  第三招:數(shù)學(xué)方法解決問題

  

  現(xiàn)在我們演繹高效C語言編寫的第二招--采用數(shù)學(xué)方法來解決問題。數(shù)學(xué)是計算機(jī)之母,沒有數(shù)學(xué)的依據(jù)和基礎(chǔ),就沒有計算機(jī)的發(fā)展,所以在編寫程序的時候,采用一些數(shù)學(xué)方法會對程序的執(zhí)行效率有數(shù)量級的提高。舉例如下,求 1~100的和。

  

  方法E:

  

  int I , j;

  

  for (I = 1 ;I<=100; I ++)

  

  {

  

  j += I;

  

  }

  

  方法F

  

  int I;

  

  I = (100 * (1+100)) / 2

  

  這個例子是我印象最深的一個數(shù)學(xué)用例,是我的計算機(jī)啟蒙老師考我的。當(dāng)時我只有小學(xué)三年級,可惜我當(dāng)時不知道用公式 N×(N+1)/ 2 來解決這個問題。方法E循環(huán)了100次才解決問題,也就是說最少用了100個賦值,100個判斷,200個加法(I和j);而方法F僅僅用了1個加法,1 次乘法,1次除法。效果自然不言而喻。所以,現(xiàn)在我在編程序的時候,更多的是動腦筋找規(guī)律,最大限度地發(fā)揮數(shù)學(xué)的威力來提高程序運行的效率。

  

  第四招:使用位操作

  

  使用位操作。減少除法和取模的運算。在計算機(jī)程序中數(shù)據(jù)的位是可以操作的最小數(shù)據(jù)單位,理論上可以用"位運算"來完成所有的運算和操作。一般的位操作是用來控制硬件的,或者做數(shù)據(jù)變換使用,但是,靈活的位操作可以有效地提高程序運行的效率。舉例如下:

  

  方法G

  

  int I,J;

  

  I = 257 /8;

  

  J = 456 % 32;

  

  方法H

  

  int I,J;

  

  I = 257 >>3;

  

  J = 456 - (456 >> 4 << 4);

  

  在字面上好像H比G麻煩了好多,但是,仔細(xì)查看產(chǎn)生的匯編代碼就會明白,方法G調(diào)用了基本的取模函數(shù)和除法函數(shù),既有函數(shù)調(diào)用,還有很多匯編代碼和寄存器參與運算;而方法H則僅僅是幾句相關(guān)的匯編,代碼更簡潔,效率更高。當(dāng)然,由于編譯器的不同,可能效率的差距不大,但是,以我目前遇到的MS C ,arm C 來看,效率的差距還是不小。

  

  對于以2的指數(shù)次方為"*"、"/"或"%"因子的數(shù)學(xué)運算,轉(zhuǎn)化為移位運算"<< >>"通??梢蕴岣咚惴ㄐ?。因為乘除運算指令周期通常比移位運算大。

  

  C語言位運算除了可以提高運算效率外,在嵌入式系統(tǒng)的編程中,它的另一個最典型的應(yīng)用,而且十分廣泛地正在被使用著的是位間的與(&)、或(|)、非(~)操作,這跟嵌入式系統(tǒng)的編程特點有很大關(guān)系。我們通常要對硬件寄存器進(jìn)行位設(shè)置,譬如,我們通過將AM186ER型80186處理器的中斷屏蔽控制寄存器的第低6位設(shè)置為0(開中斷2),最通用的做法是:

  

  #define INT_I2_MASK 0x0040

  

  wTemp = inword(INT_MASK);

  

  outword(INT_MASK, wTemp &~INT_I2_MASK);

  

  而將該位設(shè)置為1的做法是:

  

  #define INT_I2_MASK 0x0040

  

  wTemp = inword(INT_MASK);

  

  outword(INT_MASK, wTemp | INT_I2_MASK);

  

  判斷該位是否為1的做法是:

  

  #define INT_I2_MASK 0x0040

  

  wTemp = inword(INT_MASK);

  

  if(wTemp & INT_I2_MASK)

  

  {

  

  … /* 該位為1 */

  

  }

  

  運用這招需要注意的是,因為CPU的不同而產(chǎn)生的問題。比如說,在PC上用這招編寫的程序,并在PC上調(diào)試通過,在移植到一個16位機(jī)平臺上的時候,可能會產(chǎn)生代碼隱患。所以只有在一定技術(shù)進(jìn)階的基礎(chǔ)下才可以使用這招。

  

  第五招:匯編嵌入

  

  在熟悉匯編語言的人眼里,C語言編寫的程序都是垃圾"。這種說法雖然偏激了一些,但是卻有它的道理。匯編語言是效率最高的計算機(jī)語言,但是,不可能靠著它來寫一個操作系統(tǒng)吧?所以,為了獲得程序的高效率,我們只好采用變通的方法--嵌入?yún)R編,混合編程。嵌入式C程序中主要使用在線匯編,即在C程序中直接插入_asm{ }內(nèi)嵌匯編語句。

  

  舉例如下,將數(shù)組一賦值給數(shù)組二,要求每一字節(jié)都相符。

  

  char string1[1024],string2[1024];

  

  方法I

  

  int I;

  

  for (I =0 ;I<1024;I++)

  

  *(string2 + I) = *(string1 + I)

  

  方法J

  

  #ifdef _PC_

  

  int I;

  

  for (I =0 ;I<1024;I++)

  

  *(string2 + I) = *(string1 + I);

  

  #else

  

  #ifdef _arm_

  

  __asm

  

  {

  

  MOV R0,string1

  

  MOV R1,string2

  

  MOV R2,#0

  

  loop:

  

  LDMIA R0!, [R3-R11]

  

  STMIA R1!, [R3-R11]

  

  ADD R2,R2,#8

  

  CMP R2, #400

  

  BNE loop

  

  }

  

  #endif

  

  再舉個例子:

  

  /* 把兩個輸入?yún)?shù)的值相加,結(jié)果存放到另外一個全局變量中 */

  

  int result;

  

  void Add(long a, long *b)

  

  {

  

  _asm

  

  {

  

  MOV AX, a

  

  MOV BX, b

  

  ADD AX, [BX]

  

  MOV result, AX

  

  }

  

  }

  

  方法I是最常見的方法,使用了1024次循環(huán);方法J則根據(jù)平臺不同做了區(qū)分,在arm平臺下,用嵌入?yún)R編僅用128次循環(huán)就完成了同樣的操作。這里有朋友會說,為什么不用標(biāo)準(zhǔn)的內(nèi)存拷貝函數(shù)呢?這是因為在源數(shù)據(jù)里可能含有數(shù)據(jù)為0的字節(jié),這樣的話,標(biāo)準(zhǔn)庫函數(shù)會提前結(jié)束而不會完成我們要求的操作。這個例程典型應(yīng)用于LCD數(shù)據(jù)的拷貝過程。根據(jù)不同的CPU,熟練使用相應(yīng)的嵌入?yún)R編,可以大大提高程序執(zhí)行的效率。

  

  雖然是必殺技,但是如果輕易使用會付出慘重的代價。這是因為,使用了嵌入?yún)R編,便限制了程序的可移植性,使程序在不同平臺移植的過程中,臥虎藏龍,險象環(huán)生!同時該招數(shù)也與現(xiàn)代軟件工程的思想相違背,只有在迫不得已的情況下才可以采用。

  

  第六招, 使用寄存器變量

  

  當(dāng)對一個變量頻繁被讀寫時,需要反復(fù)訪問內(nèi)存,從而花費大量的存取時間。為此,C語言提供了一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,使用時,不需要訪問內(nèi)存,而直接從寄存器中讀寫,從而提高效率。寄存器變量的說明符是register。對于循環(huán)次數(shù)較多的循環(huán)控制變量及循環(huán)體內(nèi)反復(fù)使用的變量均可定義為寄存器變量,而循環(huán)計數(shù)是應(yīng)用寄存器變量的最好候選者。

  

  (1) 只有局部自動變量和形參才可以定義為寄存器變量。因為寄存器變量屬于動態(tài)存儲方式,凡需要采用靜態(tài)存儲方式的量都不能定義為寄存器變量,包括:模塊間全局變量、模塊內(nèi)全局變量、局部static變量;

  

  (2) register是一個"建議"型關(guān)鍵字,意指程序建議該變量放在寄存器中,但最終該變量可能因為條件不滿足并未成為寄存器變量,而是被放在了存儲器中,但編譯器中并不報錯(在C++語言中有另一個"建議"型關(guān)鍵字:inline)。

  

  下面是一個采用寄存器變量的例子:

  

  /* 求1+2+3+….+n的值 */

  

  WORD Addition(BYTE n)

  

  {

  

  register i,s=0;

  

  for(i=1;i<=n;i++)

  

  {

  

  s=s+i;

  

  }

  

  return s;

  

  }

  

  本程序循環(huán)n次,i和s都被頻繁使用,因此可定義為寄存器變量。

  

  /*www.cyuyan.com.cn*/

  

  第七招: 利用硬件特性

  

  首先要明白CPU對各種存儲器的訪問速度,基本上是:

  

  CPU內(nèi)部RAM > 外部同步RAM > 外部異步RAM > FLASH/ROM

  

  對于程序代碼,已經(jīng)被燒錄在FLASH或ROM中,我們可以讓CPU直接從其中讀取代碼執(zhí)行,但通常這不是一個好辦法,我們最好在系統(tǒng)啟動后將FLASH或ROM中的目標(biāo)代碼拷貝入RAM中后再執(zhí)行以提高取指令速度;

  

  對于UART等設(shè)備,其內(nèi)部有一定容量的接收BUFFER,我們應(yīng)盡量在BUFFER被占滿后再向CPU提出中斷。例如計算機(jī)終端在向目標(biāo)機(jī)通過RS-232傳遞數(shù)據(jù)時,不宜設(shè)置UART只接收到一個BYTE就向CPU提中斷,從而無謂浪費中斷處理時間;

  

  如果對某設(shè)備能采取DMA方式讀取,就采用DMA讀取,DMA讀取方式在讀取目標(biāo)中包含的存儲信息較大時效率較高,其數(shù)據(jù)傳輸?shù)幕締挝皇菈K,而所傳輸?shù)臄?shù)據(jù)是從設(shè)備直接送入內(nèi)存的(或者相反)。DMA方式較之中斷驅(qū)動方式,減少了CPU 對外設(shè)的干預(yù),進(jìn)一步提高了CPU與外設(shè)的并行操作程度。


本文標(biāo)簽: 標(biāo)簽  簡介  軟件  java  

為您推薦

WPS Office手機(jī)版如何手寫簽名

WPS Office手機(jī)版如何手寫簽名?手機(jī)版WPS Office怎么手寫簽名?很多用戶想知道手機(jī)版的WPS Office怎么手寫簽名,WPS Office手機(jī)

2022-11-30 00:19

WPS Office手機(jī)版最近文檔如何刪除

WPS Office手機(jī)版最近文檔如何刪除?在手機(jī)版的WPS Office內(nèi),每次打開的文件都會在最近文檔中顯示,那如何刪除最近文檔內(nèi),WPS Office手機(jī)

2022-11-30 00:17

WPS Office手機(jī)版怎么找回丟失的文檔

WPS Office手機(jī)版怎么找回丟失的文檔?當(dāng)我們不小心將WPS office手機(jī)版的文檔刪除之后,該怎么找回來呢,丟失的文檔怎么找回,WPS Office手

2022-11-30 00:17

手機(jī)版WPS(手機(jī)版wps怎么首行縮進(jìn)2字符)

手機(jī)版WPS Office怎么使用?WPS Office是一款辦公軟件,我們可以使用WPS Office創(chuàng)建文檔、表格、演示等等,那WPS Office怎么使用

2022-11-30 00:15

手機(jī)版WPS(手機(jī)版wps怎么首行縮進(jìn)2字符)

手機(jī)版WPS Office怎么做表格?表格可以用來做數(shù)據(jù)統(tǒng)計等等,非常的好用方便,那怎么使用手機(jī)版WPS Office制作表格呢,手機(jī)版WPS Office怎么

2022-11-30 00:15

手機(jī)版WPS 手機(jī)版wps怎么首行縮進(jìn)2字符

手機(jī)版WPS Office使用教程是什么?很多用戶對于WPS Office手機(jī)版還不知道如何使用,怎么使用手機(jī)版WPS Office,手機(jī)版WPS Office

2022-11-30 00:15