天天看點

程式設計技巧程式設計技巧

java

C++

比如在判斷兩個浮點數 a 和 b 是否相等時,不要用 a==b,應該判斷二者之差的絕對值

fabs(a-b) 是否小于某個門檻值,例如 1e-9。

判斷一個整數是否是為奇數,用 x % 2 != 0,不要用 x % 2 == 1,因為 x 可能是負 數。用 char 的值作為數組下标(例如,統計字元串中每個字元出現的次數),要考慮到 char 可能是負數。有的人考慮到了,先強制轉型為 unsigned int 再用作下标,這仍然 是錯的。正确的做法是,先強制轉型為 unsigned char,再用作下标。以下是關于 STL 使用技巧的,很多條款來自《Effective STL》這本書。

vector 和 string 優先于動态配置設定的數組:

首先,在性能上,由于 vector 能夠保證連續記憶體,是以一旦配置設定了後,它的性能跟 原始數組相當;

其次,如果用 new,意味着你要確定後面進行了 delete,一旦忘記了,就會出現 BUG,`且這樣需要都寫一行 delete,代碼不夠短;

再次,聲明多元數組的話,隻能一個一個 new,例如:

盡量使用final修飾符。

帶有final修飾符的類是不可派生的。在JAVA核心API中,有許多應用final的例子,例如java.lang.String。為String類指定final防止了使用者覆寫length()方法。另外,如果一個類是final的,則該類所有方法都是final的。java編譯器會尋找機會内聯(inline)所有的final方法(這和具體的編譯器實作有關)。此舉能夠使性能平均提高50%。不要在循環中使用Try/Catch語句,應把Try/Catch放在循環最外層。

盡量重用對象

特别是String對象的使用中,出現字元串連接配接情況時應使用StringBuffer代替,由于系統不僅要花時間生成對象,以後可能還需要花時間對這些對象進行垃圾回收和處理。是以生成過多的對象将會給程式的性能帶來很大的影響.

盡量使用局部變量。

調用方法時傳遞的參數以及在調用中建立的臨時變量都儲存在棧(Stack)中,速度較快。其他變量,如靜态變量,執行個體變量等,都在堆(Heap)中建立,速度較慢。

不要重複初始化變量

預設情況下,調用類的構造函數時,java會把變量初始化成确定的值,所有的對象被設定成null,整數變量設定成0,float和double變量設定成0.0,邏輯值設定成false。當一個類從另一個類派生時,這一點尤其應該注意,因為用new關鍵字建立一個對象時,構造函數鍊中的所有構造函數都會被自動調用。

這裡有個注意,給成員變量設定初始值但需要調用其他方法的時候,最好放在一個方法比如initXXX()中,因為直接調用某方法指派可能會因為類尚未初始化而抛空指針異常,

java+Oracle

java中内嵌的SQL語言應盡量使用大寫形式,以減少Oracle解析器的解析負擔。資料庫連接配接.java程式設計過程中,進行資料庫連接配接,I/O流操作,在使用完畢後,及時關閉以釋放資源。因為對這些大對象的操作會造成系統大的開銷。

建立對象

過分的建立對象會消耗系統的大量記憶體,嚴重時,會導緻記憶體洩漏,是以,保證過期的對象的及時回收具有重要意義。JVM的GC并非十分智能,是以建議在對象使用完畢後,手動設定成null。

同步機制

在使用同步機制時,應盡量使用方法同步代替代碼塊同步。

減少對變量的重複計算

“`

for(int i=0;i

慎用異常,異常對性能不利。

抛出異常首先要建立一個新的對象。Throwable接口的構造函數調用名為fillInStackTrace()的本地方法,fillInStackTrace()方法檢查棧,收集調用跟蹤資訊。隻要有異常被抛出,VM就必須調整調用棧,因為在處理過程中建立了一個新的對象。

異常隻能用于錯誤處理,不應該用來控制程式流程。

Error是擷取系統錯誤的類,或者說是虛拟機錯誤的類。不是所有的錯誤Exception都能擷取到的,虛拟機報錯Exception就擷取不到,必須用Error擷取。

通過StringBuffer的構造函數來設定他的初始化容量,可以明顯提升性能。

StringBuffer的預設容量為16,當StringBuffer的容量達到最大容量時,她會将自身容量增加到目前的2倍+2,也就是2*n+2。無論何時,隻要StringBuffer到達她的最大容量,她就不得不建立一個新的對象數組,然後複制舊的對象數組,這會浪費很多時間。是以給StringBuffer設定一個合理的初始化容量值,是很有必要的!

合理使用java.util.Vector

Vector與StringBuffer類似,每次擴充容量時,所有現有元素都要指派到新的存儲空間中。Vector的預設存儲能力為10個元素,擴容加倍。

vector.add(index,obj) 這個方法可以将元素obj插入到index位置,但index以及之後的元素依次都要向下移動一個位置(将其索引加 1)。 除非必要,否則對性能不利。

同樣規則适用于remove(int index)方法,移除此向量中指定位置的元素。将所有後續元素左移(将其索引減 1)。傳回此向量中移除的元素。是以删除vector最後一個元素要比删除第1個元素開銷低很多。删除所有元素最好用removeAllElements()方法。

如果要删除vector裡的一個元素可以使用 vector.remove(obj);而不必自己檢索元素位置,再删除,如int index = indexOf(obj);vector.remove(index);

當複制大量資料時,使用System.arraycopy();

代碼重構,增加代碼的可讀性。

不用new關鍵字建立對象的執行個體。

用new關鍵詞建立類的執行個體時,構造函數鍊中的所有構造函數都會被自動調用。但如果一個對象實作了Cloneable接口,我們可以調用她的clone()方法。clone()方法不會調用任何類構造函數。

下面是Factory模式的一個典型實作。

乘除法如果可以使用位移,應盡量使用位移,但最好加上注釋,因為位移操作不直覺,難于了解。

不要将數組聲明為:public static final。

HaspMap的周遊

<code>Map&lt;String, String[]&gt; paraMap = new HashMap&lt;String, String[]&gt;(); for( Entry&lt;String, String[]&gt; entry : paraMap.entrySet() ) { String appFieldDefId = entry.getKey(); String[] values = entry.getValue(); }</code>

利用散列值取出相應的Entry做比較得到結果,取得entry的值之後直接取key和value。

array(數組)和ArrayList的使用。array 數組效率最高,但容量固定,無法動态改變,ArrayList容量可以動态增長,但犧牲了效率。

單線程應盡量使用 HashMap, ArrayList,除非必要,否則不推薦使用HashTable,Vector,她們使用了同步機制,而降低了性能。

StringBuffer,StringBuilder的差別在于:java.lang.StringBuffer 線程安全的可變字元序列。一個類似于String的字元串緩沖區,但不能修改。StringBuilder與該類相比,通常應該優先使用StringBuilder類,因為她支援所有相同的操作,但由于她不執行同步,是以速度更快。為了獲得更好的性能,在構造StringBuffer或StringBuilder時應盡量指定她的容量。當然如果不超過16個字元時就不用了。

相同情況下,使用StringBuilder比使用StringBuffer僅能獲得10%~15%的性能提升,但卻要冒多線程不安全的風險。綜合考慮還是建議使用StringBuffer。

盡量使用基本資料類型代替對象。

用簡單的數值計算代替複雜的函數計算,比如查表方式解決三角函數問題。

使用具體類比使用接口效率高,但結構彈性降低了,但現代IDE都可以解決這個問題。

考慮使用靜态方法

如果你沒有必要去通路對象的外部,那麼就使你的方法成為靜态方法。她會被更快地調用,因為她不需要一個虛拟函數導向表。這同僚也是一個很好的實踐,因為她告訴你如何區分方法的性質,調用這個方法不會改變對象的狀态。

應盡可能避免使用内在的GET,SET方法。

android程式設計中,虛方法的調用會産生很多代價,比執行個體屬性查詢的代價還要多。我們應該在外包調用的時候才使用get,set方法,但在内部調用的時候,應該直接調用。

避免枚舉,浮點數的使用。

二維數組比一維數組占用更多的記憶體空間,大概是10倍計算。

SQLite資料庫讀取整張表的全部資料很快,但有條件的查詢就要耗時30-50MS,大家做這方面的時候要注意,盡量少用,尤其是嵌套查找!