這幾個編程小技巧,讓你代碼效率提高一個檔次

2021-02-21 扣丁學堂

夥伴們在編程過程中

有的人說我敲代碼又不好看還慢

怎麼辦?

今天CoCo醬給大家介紹幾個編程小技巧

讓你的代碼迅速提高檔次

 1 

for循環變量初始化

在c語言中,我們常常這樣使用for語句:

for (int i = 0; i < strlen(s); i++)

這看起來似乎很完美,代碼也很漂亮,讓我們再看看另一種寫法:

for (int i = 0, len = strlen(s); i < len; i++)

二者唯一的不同在於後者用len變量將字符串s的長度保存了,在條件判斷時直接將i與len比較。

第二種方法用一個額外變量len避免了每次條件判斷都要重複執行函數strlen(s),而執行該函數是非常耗時的(假設字符串的長度為n,函數執行的複雜度為O(n)),尤其是當for循環體的語句比較少,字符串比較長的時候。

在很多leetcode題目中,兩種不同的寫法需要的運行時間相差巨大。

同樣在C++、Java中,這種寫法for (int i = 0; i < s.length(); i++),也是不值得推薦的,儘管C++編譯時期有的編譯器會將length()函數用內聯或者一個確定的變量來替代,Java也會將其用「屬性」來替代,但我仍然傾向於使用後者。

有意思的是,在Python的語法中,for循環用這種方式來表示:

這就避免了重複去求字符串s的長度,這種方法既有語義感,又獲得了高性能。

 2 

變量定義位置(for循環內部還是外部)

//內部
for (int i = 0; i < 10; i++)
{
 string s = ss[i];
 ...
}


//外部
string s;
for (int i = 0; i < 10; i++)
{
 s = ss[i];
 ...
}

如果定義在內部,每次循環都要重新定義string變量s,意味著每次循環都要調用構造和析構函數;而定義在外部每次循環只需要調用複製構造函數。

一般建議將大的對象定義到外部,提高運行效率,把小的對象定義在裡面,提高程序可讀性。

 1 

在乘以2(或2的整數次冪)或除以2(或2的整數次冪)的時候儘量用位運算來替代。

 2 

儘量減少使用除法運算(可以適當轉換為乘法,如條件判斷時將if (a == b / c)替換為if (a * c == b)。除法運算需要更多的移位和轉換操作,往往需要的時間是相應乘法的兩倍)

 3 

多使用+=、-=、*=、/=等複合運算符,以加一為例,效率由高到低是(i++ 、 i += 1 、 i = i + 1)

 4 

多掌握一些小巧的庫函數,例如:swap, max, min, sort, qsort, ati, stoi...它們用起來方便,效率更是比一般人寫的代碼高。

inline讓函數內聯,建議編譯器將函數體代碼「複製粘貼」到函數調用處,在函數體短小,函數調用又比較頻繁的時候能有效避免因函數調用帶來的內存開銷(因為每一次調用函數系統都會生成許多額外的變量)。

const不僅僅可以保證其修飾的變量不被修改,提高程序的穩定性,同時也讓編譯器更好地為我們優化代碼。

舉個例子:我們如果用const修飾某一個常量,那麼程序中所有用到該常量的地方都會用其值來代替,這樣就避免了讀取其地址而浪費時間。

&修飾返回值類型和參數類型表示採取引用的方式傳遞,避免了對象賦值構造所需的時間和內存。

除了CPU,就是寄存器和緩存的訪問速度最高了,一般不建議我們自己定義寄存器變量和控制數據緩存,編譯器會自動幫我們把經常用到的一些數據放到緩存和寄存器中。

但是,了解一些編譯器控制數據的依據對編程也有極大幫助。一般來說,放到寄存器/緩存的數據優先級為:用register修飾的變量,循環控制變量,auto局部變量,靜態變量,用戶自己分配的內存數據。

 1 

訪問容器中元素的時候儘量使用迭代器而不是下標或者指針。在剛從C語言轉到C++的那段時間,我非常不適應迭代器的用法,總覺得下標訪問多好,與for循環搭配在一起簡直是無敵的存在。

後來我才慢慢發掘出迭代器的眾多優勢。

首先,迭代器訪問元素類似與指針,相對於下標訪問不用根據下標值計算地址,這在循環中能夠節省不少時間。

其次,迭代器作為指針一種延拓,能更好的代表並操作其所指的對象,而在下標訪問中我們往往用一個int值pos來表示pos下標下的元素,沒有面向對象編程的直觀。再次,迭代器為我們訪問各種容器(數組,vector,list,map,queue,deque,set …)中的元素提供了統一的方法,其作用類似於「語法糖」,讓編程更加簡單、方便。

 2 

另外在使用迭代器的自增和自減運算符需要注意,iterator++,和++iterator的效率有天壤之別。兩種自增方式的運算符重載如下:

iterator & operator++()
{  // 前增
 ++*this;
 return (*this);
}

iterator operator++(int)
{  // 後增
 iterator temp = *this;
 ++*this;
 return (temp);
}

vector容器毫無疑問是C++STL使用最為頻繁的容器了,當然這個強大容器的使用也包含了很多的小技巧。

 1 

在適當時候使用emplace和emplace_back函數來替代insert和push_back函數。

它們之間的區別很明顯,insert和push_back函數參數是vector容器裡面的模板對象,而帶emplace的函數參數是模板對象的構造函數的參數,這意味著後者將模板對象插入到vector容器的過程中不用先生成好對象,而是可以直接利用參數構造。

當然如果模板對象已經是生成好的,那就沒有必要用emplace函數了。在很多循環遞歸迭代中,往往需要反覆向vector容器中添加對象,這時候額外構造一個對象所需要的時間和空間就不容忽視了,因此這是一個vector進階用法的好trick。

 2 

vector容器的底層實現是數組,並且在當元素大於最大容量的時候會重新生成一個更大的數組,將原來數組中的對象複製構造到新數組中。

由於要重新分配大量內存以及反覆調用複製構造函數,這對時間和空間的開銷是巨大的。為了減少內存的重新分配,我們可以適當的估計我們需要保存的元素數量,並在vector初始化的時候指定其capacity。

這種方法很直接但也有其缺點,就是我們往往很難在開始的時候就估計準確我們要保存的元素數量(如果能,我們就直接用數組得了)。

一個很好的解決辦法是:將vector中保存的元素改為指針,指針指向我們真正想要保存的對象。由於指針相對於其所指向的對象來說佔用內存很小,而且在複製的時候不用調用複製構造函數,因此以上提到的一些缺點都能很好的克服。

事實上,對於能夠熟練控制內存分配的老碼農來說,這種vector + 指針的方式是十分完美的。

在進入討論之前,我們先思考下面這個例子:

一個班的數學成績如下:74、76、78、94、97、68、77、65、54、89…,總共有50個數據。

要求用程序將分數為優秀(>=80)、良好(>=70)、及格(>=60)、不及格(>=0)四個分數段。

for 所有學生分數
 if 分數 < 60
   歸為不及格段
 else if 分數 < 70
   歸為及格段
 else if 分數 < 80
   歸為良好段
 else 
   歸為優秀段

這個偽代碼邏輯沒有問題,但是就這個數據來看這段代碼運行效率糟透了。

由於這個班的數學成績絕大多數是良好和優秀,而這個程序需要三次if判斷才能將分數歸為良好,三次if判斷加上一個else才能將分數歸為優秀,所以絕大多數前兩個if判斷是不必要的。我們將if判斷語句的順序變換下:

for 所有學生分數
 if 分數 >= 80
   歸為優秀段
 else if 分數 >= 70
   歸為良好段
 else if 分數 >= 60
   歸為及格段
 else 
   歸為不及格段

在這個偽代碼中絕大多數分數都在前兩個if語句中完成了分段。兩者的時間效率相差巨大,實際運行也發現,前者是後者運行時間的兩倍多。

switch語句的底層實現主要有三種方式:轉換為if else 語句,跳轉表,樹形結構。

當分支比較小時,編譯器傾向於轉換為if else語句,當分支比較多,分支範圍很廣時,用樹形結構,當分支數量不算多,分支範圍緊湊時,用跳轉表。

跳轉表的底層實現是數組映射,對條件轉換的效率為O(1),相比於另外兩種方式優勢明顯,因此我們應該儘量控制分支的數量,以及讓各個分支的int型數據緊湊。

不知道這些技巧小夥伴們都了解了嗎?

#你在編程過程中還有什麼小技巧#

相關焦點

  • 編程效率是什麼?一個例子告訴你(附代碼)
    軟體開發過程中很多時候要考慮內存資源和程序執行效率等問題,當然對於初學者來說可以不必在意這些,但在編寫代碼時一定要注意有這麼一回事。本文將以一個簡單的例子來說明效率的問題,以供大家參考、學習。編程效率一個例子:for+if以下代碼實現的功能是一樣的,只不過在編碼上結構不同。
  • 這三個技巧,讓你的代碼可讀性提高300%
    原始碼是程式設計師耗盡了心血和精力的作品,所以不應當存在「快刀斬亂麻」的現象。忽視這些規定看似讓代碼生成速度加快,但事實上往往導致事倍功半。代碼敲一次,閱讀無數次。因此,優化代碼提高可讀性顯得尤為重要。為了幫助生成高度可讀的代碼,本文歸納總結了必須遵守的3個重要規定。遵循這些規則可以幫助使用代碼的人員維護、擴展和調整代碼。
  • 4個Shell小技巧,提高機器學習生產效率
    本文轉自AI新媒體量子位(公眾號 ID: QbitAI)在機器學習的實踐過程中,用好Shell能幫你很多節省時間。最近,有位來自ETHZ的學生分享了一些Shell小技巧。對程式設計師來說,這些技巧更重要的是讓你的思維從瑣碎小事中解脫出來,大大提高了工作效率。下面就是他分享的4個tips。
  • 如果你也基於pandas做數據分析,分享這幾個提高效率的小知識點
    本文基於數據分析庫pandas,分享我在工作中常常需要使用的幾個關於數據定位的常用語法以及幾個小知識點。01loc和iloc目前pandas的版本已經取消了ix和at等語法,推薦使用的是loc和iloc這兩種語法定位數據loc是location的縮寫,iloc是index_location的縮寫,前者是基於標籤(標籤是指通過列名或者索引名定位數據),後者是基於索引
  • 「收藏」提高PyCharm效率的10個小技巧
    PyCharm是最常用的python開發IDE,程式設計師可以通過PyCharm強大的功能節約大量時間用來 (摸魚) 工作,提高生產效率。阿狗總結了10個自己會用到的PyCharm中可以提高擼碼效率的小技巧,希望能幫助到需要的小夥伴。
  • 實例集錦與提高技巧,助你高效學習LabVIEW
    所以,首先你要明白,不管你現在處於哪個階段,學習方法和效率遠遠大於學習時長,你付出的努力上來得重要。回到上述提出的問題,「感覺網上有關LabVIEW資料很少,尤其是相關實例」。這裡編者覺得需要糾正一下,不管你說的學習LabVIEW的各種資料少,還是特指你說的樣例實例代碼,其實這些內容在網上很多,並不是少而且太多了!
  • 提高編程質量和效率使用UG模板技巧
    大家好,我是橘子,今天給大家分享的是關於UG編程實際案例.喜歡我分享的文章或者還需要別的學習資料可以關注我私信UG都可以免費領取提高編程質量和效率使用UG模板技巧 通過建立UG編程模板的方式,以提高我們用ug編程的工作質量和效率,並
  • 「技巧篇」循環代碼優化技巧
    ,養成一種好的編程習慣,避免一些低效弱智的做法。雖然現在計算機越來越快,內存越來越大,很多人會覺得一頓操作猛如虎之後可能才優化了 1 s,實在太微不足道了,但是可別忘了,你以後編的程序可不是給你一個人用的,可能是伺服器程序,你這個慢 1 s,一天來個百萬次千萬次的請求,那對於你的運行效率來說,那是拖慢了成千上萬倍。
  • 程式設計師必備的編程神器,MAX你的代碼質量!
    自己學習了編程也有一年的時間了,在這一年的時間裡面一直在學習效率和工作舒適度提升的工具和工作方法,探索和建立了自己的一套工作方法,也在不斷地進行系統和工具的更新。自此以後發誓,一定要好好學習新的軟體工具和工作方法,讓工作效率和質量全方位提高。所以最直接原因就是珍惜生命,提高效率。
  • 效率提升30倍 無代碼開發讓「小白」也能編程
    效率提升30倍 無代碼開發讓「小白」也能編程記者 唐 婷近日,有外媒指出,在過去35年,軟體行業發生了一些重大轉變。其中之一便是,越來越多的軟體應用程式,已構建了基於無代碼原則的平臺,軟體業的未來將是屬於無代碼平臺的。那麼,代碼在軟體編寫中扮演著怎樣的角色?什麼是無代碼平臺?軟體編寫是否真的可以做到無代碼?無代碼軟體的優勢有哪些?
  • 與代碼面對面,「獨自編程」讓工作效率更高
    在編程領域,如果你曾經是一名自由職業者,你就會知道在最後期限內迷失自己並且一次又一次陷入同樣的錯誤是多麼容易。獨自編程法獨自編程法(Forever Alone Programming)是一位 ID 為 nopara73 的開發者開源的編程方法。如果你喜歡一個人靜靜的進行編程工作,你可以看看這個方法。
  • 這些調試技巧都不會,不要說會VBA編程
    程序調試是編程過程的重要組成部分,程序調試可以讓我們修正程序的語法錯誤和邏輯錯誤,並能儘可能地減少程序中的bug。Excel的VBE也提供了豐富的調試工具,如斷點調試,立即窗口和監視窗口等。下面將介紹幾個常用的VBA編程調試技巧。
  • 這3個Excel實用小技巧,讓你的工作效率提高3倍
    對於大多數朋友來講,Excel都是一個對工作和生活幫助很大的軟體。我們面試求職、統計數據和完成工作任務,都需要Excel表格的協助,才能讓我們的工作成果有一個比較完美的展現。可以說,擅長Excel表格技巧的朋友,就算不會總是加薪升職,在辦公室裡也永遠會是最受歡迎的人。
  • 日常Word辦公小技巧,幫你快速提高工作效率!
    你還沒有學會一些Word技巧?作為一名職場人,我們每天都會與辦公軟體與辦公文件打交道。其中最常見的就是使用Word來閱讀文件、編輯文件等。想要在使用Word時更加的輕鬆便捷,我們得掌握一些Word辦公技巧。
  • 玩遊戲學編程:8個能夠快速提高編程水平的小遊戲
    沒有練習,你就不會看到學習曲線上的結果。這些問題有一個解決方案,它適用於學習如何編寫代碼或提高您對特定語言的知識。編程遊戲!今天我們將列出一份最佳編程遊戲的列表。1. RobocodeRobocode擁有龐大的粉絲群,這要歸功於它引人入勝且平衡的遊戲過程。想想看,早在2000年推出的這款遊戲至今仍被粉絲們定期更新和維護。它使您編寫真正的代碼。在Robocode中,你必須使用一些流行的程式語言為你的機器人坦克編寫AI,包括Java和c#。所以每次你玩遊戲的時候,你都可以練習你真正的和適用的編碼技巧。這是一個開源遊戲。
  • 想要提高Excel辦公效率,這幾個小技巧你不能缺少
    想要提高Excel辦公效率,這幾個小技巧你不能缺少大家好,很高興又見面了。最近幾天,由於工作的原因耽擱沒有持續更新分享,在這裡向大家道一聲抱歉。雖然,短暫的中斷讓人少了一點小「負擔」,但是相信,學習將會永無止境。
  • 教你幾個提高標書製作效率的小技巧~
    今天,小編給大家分享的是標書製作過程中的一些Word排版技巧!Word應該是辦公軟體中使用頻率最高的工具,但卻一直不被很多人重視,以為它簡單很容易學,但實際很多人並沒有掌握其基本用法,以至於自己的工作效率未能得到有效提升······      好啦~ 話不多說,我們開始上課吧!
  • 這幾個PPT小技巧,讓你快速提升工作效率
    快樂的周一,從離開周末開始~不知道有沒有悲慘的兄弟,周末還拿來在加班做PPT,如果有,我精神、肉體上全都同情你~有一說一,做PPT還挺費時間的。特別是在放鬆的時候,例如周末啊、假期啊,工作效率是異常低的,可能大半天憋不出幾頁來。
  • 自從學會這些小技巧,我操作電腦的效率提高了10倍
    自從學會這些小技巧,我操作電腦的效率提高了10倍5.你知道嗎?其實windows系統自帶錄像功能。是不是需要同時打開多個小窗口,然後操作完了再一一關閉?NO!沒有那麼麻煩。只需要同時按下window鍵+X鍵,一次滿足你的所有願望!
  • 提高文案寫作效率小技巧
    大家在日常生活中,肯定會遇到很多需要寫文案的場景,比如會議記錄,新媒體推廣運營,論文答辯,這些都是需要一定的文字功底,所以如何提高文案寫作技巧,還是一個很普遍的問題需要解決。今天就來告訴大家一個提高效率的小技巧!