J2ME開發優化

J2ME開發優化
1、猜測Vector的長度

2、使用局部變量
3、避免字符串比較
4、將變量和方法聲明爲final和static,以加快訪問
5、使用惰性實例化
6、處理outofmemoryError錯誤
7、使用數組而不是對象
8、倒計至零的迭代循環,因爲和零比較將會較快
9、把引用設置爲NULL
10、最大限度的減少方法調用的次數
11、使用移位運算取代乘以二的運算
12、避免類型轉換
13、只要有可能、儘量使用Int
14、避免使用異常
相對於J2SE和J2EE開發,很多反常規的方法倒是更加適合J2ME開發
部分內容摘自《More Java Pitfalls 中文版》

J2me程序由於其特殊的運行環境限制,所以優化就顯得比較重要,以下是我在學習j2me編程所收集的一些技巧和自己的心得。
  本文主要是說明j2me平臺上的特殊優化方法,與j2se重複的一些技巧就不再贅述了。
  1.顯示圖象時確定好你的fps,最好先做幾次小實驗,這樣能讓你在顯示效果和運行速度上有比較好的平衡。
  2.GamaCanvas.getGraphics()每次都會產生一個全新的對象,但是對這些對象的操作都是對同一個graphics,所以還是隻取一次供後面使用。
  3.讓多個對象使用同樣的監聽器,比如讓主MIDlet類實現CommandListener和ItemStateListener接口。
  4.考慮使用手機開發商提供的一些sdk,沒人會比他們更瞭解他們手機,所以有些時候能顯著提高速度,特別是圖片,視頻使用方面。
  5.使用監視工具分析MIDlet的瓶頸,wtk和各個公司提供的開發包裏都會有,可以找到程序的弱點。如果是在手機上,用timer測試你認爲有可以的地方。
  6.使用System.gc(),在無線程阻塞的情況下可以有效的緩解內存壓力,但是有些公司不是太推薦使用(如nokia).sun的說法也是越低端的機子執行的越慢,總之,慎用吧。
  7.用固定的數組代替使用Vector。
  8.圖片的優化。考慮使用設備的規格,可能高分辨率的圖片不一定顯示的出來。
  9.不用的對象賦值爲null,爲更快的回收
  10.用混淆器處理你的類文件,防止反編譯,還有一個好的副作用就是它減小>
=============================================================
通過Profiler對各種函數及程序的測試,我總結如下結論:

  ·僅當你需要的時候纔去優化代碼!
  ·僅優化那些最耗時的代碼!
  ·使用Profiler去查找哪裏需要優化!
 
  ·記住Profiler不代表真機上的優化結果,使用System Timer來在真機上做最後的測試!

  ·在做低級優化之前,總是要先思考算法是否是最優!
  ·繪圖是很佔用時間的,所以儘可能的減少Graphics函數的調用!
  ·儘可能的使用SetClip()來減少繪圖區域,相對於SetClip(),drawImage()所花的時間會更可觀!
  ·儘可能的將變量定義在循環以外!
  ·盡最大可能的進行對需要的數據進行預先計算並將結果保存在緩衝裏!
  ·String類很容易產生垃圾內存,儘可能的使用StringBuffer代替String或用final static來定義之!
  ·假設是不被接受的,一切要以真機爲據!
  ·儘量使用static final修飾函數,而避免synchronized修飾符!
  ·對於頻繁調用的函數要使用儘可能少的參數!
  ·儘可能的不使用函數調用!
  ·儘可能的使用<<和>>來代替*和/!
  ·使用位操作來代替%運算!
  ·與0比較比與其他數值比較快!
  ·數組存取比C語言慢,儘可能不在循環中存取數組!
  ·局部變量比其他類型的變量運算要快!
  ·在switch()中儘量使用連續的小數值判斷!
  ·儘量使用乘法而不使用除法!
  
  ·儘量使用已有算法!

=========================================================

一般就着手於代碼的優化,像電力就沒辦法了,
J2ME的編程,由於平臺的原因,不能像電腦的編程一樣,採用很良好的設計,要知道增加代碼的數量就可能造成一定
的影響,所以不能完全追求設計而編寫,比如setter,getter方法如果不涉及自定義操作的話,可以將變量設成public的,這樣一來就可以避免方法調用所產生的開銷
還有,圖片使用方面,能使用拼圖就儘量使用拼圖,不要用一張過大的圖片,圖片的質量能壓縮儘量壓縮,顏色能少用
就儘量少用.
聲音也是一樣,儘量用短小的聲音,不要使用太大的聲音.


儘量少用對象,不用的對象及時NULL掉,圖片,聲音資源也一樣,用的時候加載,不用的時候NULL掉,可以在適當的時候,用Runtime.getRuntime().gc()清下內存,畫圖的時候用rapint(0,0,屏幕寬,屏幕高),防止超出屏幕外的部分也繪製,儘量用MIDP1.0的方法,效率比2.0的要高,import的時候,只import要用的類,不用的就不導入,記得打包的時候要混淆下,用單線程,少用VECTOR,儘量用定長的對象數組。
---------------------------------------------------------------------------

[原創]J2me的優化之路
[watermark]J2me的優化之路 很多介紹優化的文章裏都提到要儘量減少class數量,但是,這真的是有必要的嗎?不錯,每增加一個空的class大概要多使用100多字節內存,打包後的體積也會有少許增加。但是這樣做的好處是更清晰的代碼結構,明確的變量使用。因爲衆所周知,java裏沒有c/c++裏的struct,union,等數據結構,j2me裏只有使用class來代替。 代碼的優化,不是用搞亂程序結構來實現的。誠然,那樣做的確可以或多或少的減小jar體積,但是代價呢?不清晰的流程,混亂的變量使用……,甚至導致無法二次修改、移植。這樣的代碼,我寧可不要。 真正的優化,是建立在清晰的結構,明確的流程之上的。合理的使用變量,優化數據結構,優化衆多不變的數據成爲常量,刪除無用的代碼諸如:System.out.println等調試時期使用的代碼。 對於運行速度的優化,幾乎是所有編程語言都通用的。請看如下僞代碼: Object m_sprite[]=new Object[5]; int i; for(i=0;i<10;i++) m_sprite[0]=xxxxxx; 在for的10次循環中,m_sprite[0]每次都要訪問2次地址。爲什麼?不要問我,有c/c++開發經驗的人都應該知道。 如何優化這個部分?請參考下面的代碼: Object m_sprite[]=new Object[5]; Object tmp; int i; tmp=m_sprite[0]; for(i=0;i<10;i++) tmp=xxxxxx; 僅僅增加一個變量,就將運行速度提高的近乎一倍。諸如類似的優化方案還有很多,多是千篇一律,大家可以從網上搜索這裏就不重複了。請記住一點,所有的優化方法幾乎都是通用的,適用於c/c++的,一樣適用於j2me。 另外,建議大家使用TimerTask,而不是Thread,除了TimerTask更精確一些外,還因爲如果使用Thread方法,就必須依靠wait或sleep來控制時間,但是這兩個方法根本無法保證精確性,幾乎每個型號的手機都不一樣。 排除手機性能的自身問題外,有一部分速度的影響是在屏幕刷新上。paint是一個異步方法,並不是保證立刻刷新,即使調用serviceRepaints也一樣。超過屏幕所能接受的刷新頻率將導致圖象的混亂和更長的延遲時間。 合理的安排資源文件也很重要,jbuilder ,eclipse都具有指定打包後文件所在路徑的功能。另外,縮短資源文件名,將多個資源文件合併爲一個文件等方法也可以有效的減小jar尺寸,原理在於zip的壓縮算法。 最後的優化,建立在一個名叫ProGuard的混淆工具上。目前最新版本是3.4,這個工具的特點是可以刪除,合併沒用到的class,方法,變量,取消package限制將所有class放到根路徑,從而大大縮小jar的尺寸。另外需要注意的一點是,class的數量,請儘量保持在26個之內。否則,混淆後的變量名不但不會縮短,反而會更長。 j2me的優化之路還很長,我僅僅是摸索到了一點點,更多的東西還需要更長的時間去發掘。以上觀點,如有不對之處,歡迎探討。[/watermark]



J2me優化
TCL 發表於 2006-3-31 13:48:00
對我的遊戲編程進行總結的時候,我發現有很多東西,都是可以進行優化的。j2me能給我們的並不一定就是我們想要的,in another word,有的東西並不適合遊戲的編程。總結如下:
1)儘量要重複利用對象;
2)不用的對象要賦爲null;
3)數組代替vector;
4)儘可能少用class,如果能用過程的方法就用,不能的話再考慮對象;
5)方法的速度比較:同步方法<接口方法<實例方法<final方法<靜態方法
6)儘量使用final static方法,當然這個方法的含量要少了,這樣可以提高速度。
7)數據成員設成public吧,省得要調用函數去修改!
8)在進行循環的時候,我們要使用++i,不要使用i++,我曾經試過,在大型的循環過程中,時間要快1倍。
9)在進行大的數組初始化的時候,最好使用讀取的方法,這樣可以省去很多內存。比如256*64的數組,如果我們使用interface的話,要用掉24616的memory,而使用讀取的方法要使用13408的內存。
 


    代碼優化的技術大致分爲兩個主要方面:高級優化,從使用的整體算法和結構出發進行的優化;低級優化,集中於孤立的代碼片斷(通常爲方法中的代碼)的優化。下面分別討論兩方面的優化:
一,高級優化
1, 感覺到就是真實
對於電影來說,我們通過攝像頭看到的都是完美的,而在拍攝現場我們看到的卻是木頭,泡沫和膠帶。所以對於電影來說,感覺到就是真實。
遊戲也一樣,只需要處理遊戲需要的東西。在遊戲開發的各個方面這都是實用的。把精力集中在使遊戲有趣和完美運行的問題上,始終只做需要做的而丟棄其他的部分。
2, 不要創建對象
減少對象創建的總數量和頻率,結果能夠大大地提高遊戲的性能。還必須小心在不經意的情況下產生String對象。
例如:graphics.drawString( 0,0,”Score:” +score );
這一句代碼會在每次被調用的時候產生一個新的String對象,在這裏就是每一楨畫面顯示時都會產生新的String對象。因此最好是只是在分數改變的時候才構造這個String。
3, 繪製屏幕
通常,在對遊戲完成大量的優化工作以後,收穫的將是一個大量時間耗費在屏幕繪圖上的遊戲。這是因爲一個遊戲的主要時耗大都集中在繪製圖像的工作上(或其他的一些基本的繪圖調用)。因此,如果一開始就可以避免繪製工作,那將是對遊戲的很好的優化。

還有就是要減少屏幕繪製,循環檢測屏幕圖像是否在某個部分發生了改變,如果沒有,就不要對那部分的屏幕進行更新。另一個方法就是增加繪製圖像的尺寸來減少單獨的繪製調用的次數。
4, 算法
最好的,也是使用最多的高級優化是對遊戲的算法方面。

二,低級優化
1, 提前繪製複雜圖像
我們已經知道,使用LCDUI繪製圖像是很慢的,因此最好是能夠避免這種繪製。其中的一個方法就是用一個預生成圖像來減少複雜圖像的繪製。進一步來講,舉例:將所有的遊戲狀態信息整合到一個面板中(得分,生命數,能量值等),然後對這些信息進行一次性同時更新。
2, 保持類和內存之間的平衡
產生新的類會增加JAR包文件的大小,因此應該儘量避免。有的時候增加了額外類的開銷可能節省了額外的內存開銷,這也是值得的。
3, 複雜值的預計算
節省運算的一個好方法就是對數值進行預運算,從而無需再調用大開銷的計算方法。一個很好的例子就是:主窗口畫布的高度和寬度就是很好的 緩存對象。例如:可以調用getHeight方法和getWidth方法一次,然後將它們的結果緩存起來,而不是在每一次繪圖中都調用這兩種方法。
4, 使用數組
在任何時候,只要可能,都應該使用數組而不是Vector,因爲數組的運行速度更快。通常面臨的唯一問題是,如果最初分配的數組空間不夠大,將需要對數組的大小進行擴充。這可以做到,但它需要對整個數組進行重建。例如:
    Public final static int[ ] eXPandArray(int [] oldArray, int expandBy)
           {
                  int [ ] newArray = new int [oldArray.length + expandBy];
                  System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
     Return newArray;
}
      任何時候,都應該儘量使用一維數組。訪問二維數組變量的速度只有訪問一維數組變量的一半。當然,仍然可以訪問二維數組的對象,只是需要加入一點點計算。例如,與其使用這條語句:
              world[y][x] = 0;
       不如下面這條語句運行的快:
        world[y*tilesWide + x] = 0;
這條語句通過行列的位置將數值轉換成一維值,實現了對數組同一元素的訪問。
5, 不要使用數組
呵呵,儘管數組的訪問比Vector快,但仍然比直接訪問變量要慢,因此如果可能就應該刪除對數組的訪問,或者爲一些常用方法中的數組尋求其他能提高性能的辦法。
6, 使用快速方法
並不是所有Java調用的方法在性能上都是相同的,方法聲明方式的不同對性能會會產生很多的影響。可以使用的最快的方法類型是靜態方法,因此應該儘可能多地將代碼置於靜態調用方法中。運行速度僅次於靜態方法的是聲明爲final的方法。運行最慢的兩種方法是在接口中定義的方法和用關鍵字synchronized聲明的方法,必須儘可能地避免使用這些類型的方法。
7, 其他優化
1)異常處理非常緩慢,不要爲一半的遊戲邏輯使用異常,只用它們來報告真正的錯誤狀態。
2)使用switch表達式比使用if條件語句塊的速度要快。
3)儘可能避免使用String對象進行運算,使用StringBuffer。
4)內嵌類的運行很慢,儘可能避免使用。
5)在完成一個引用的使用後將它設爲null。
6)不要浪費時間來將一個對象初始化爲null或0,java虛擬機會替我們完成這樣的初始化
7)多思考新方法,這會使我們的大腦運轉的更快。
8)如果可能,儘量使用static,它們運行都很快。它同時適用於方法和域,這條規則就是,如果它可以是靜態的,那麼就把它聲明爲靜態的。
9)避免類型轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章