android畫圖的效能分析
一,往直接View裡畫圖。
用onDraw (Canvas g)向View裡畫圖.
我在模擬器上測序了4種向View裡畫320X480圖的效能:
首先,畫inmutable的bitmap圖最快。(9毫秒)
其次,畫mutable的bitmap圖比較慢。(19毫秒)
再其次,畫非Alpha的RGB資料更慢。(34毫秒)
最後,畫Alpha的RGB資料最慢。(43毫秒)
測試代碼1:
long times[]=new long[4];
int cnt=0;
protected void onDraw (Canvas g)
{
long time=System.currentTimeMillis();
if(img!=null)
{
boolean hasAlpha=!true;
time=System.currentTimeMillis();
g.drawBitmap(img.getBitMap(), 0, 0, null);
time=(System.currentTimeMillis()-time);
times[0]+=time;
int [] colors=new int [Game.width*Game.height];
for(int i=0;i<colors.length;i++)
colors=0xFF0000FF;
Bitmap bitMap=Bitmap.createBitmap(colors, Game.width, Game.height, Bitmap.Config.ARGB_8888);
time=System.currentTimeMillis();
g.drawBitmap(bitMap, 0, 0, null);
time=(System.currentTimeMillis()-time);
times[1]+=time;
time=System.currentTimeMillis();
hasAlpha=false;
g.drawBitmap(colors, 0, Game.width, 0, 0, Game.width, Game.height, hasAlpha, null);
time=(System.currentTimeMillis()-time);
times[2]+=time;
time=System.currentTimeMillis();
for(int i=0;i<colors.length;i++)
colors=0xF0000FFF;
hasAlpha=true;
time=System.currentTimeMillis();
g.drawBitmap(colors, 0, Game.width, 0, 0, Game.width, Game.height, hasAlpha, null);
time=(System.currentTimeMillis()-time);
times[3]+=time;
cnt++;
}
if(cnt%10==0)
{
System.out.println("run cnt:"+cnt);
System.out.println("time for mutable bitmap:"+times[0]
+" inmutable bitmap:"+times[1]
+" no alpha colors:"+times[2]
+" Alpha clors:"+times[3]);
System.out.println("average time for mutable:"+times[0]/cnt
+" inmutable:"+times[1]/cnt
+" no alpha colors:"+times[2]/cnt
+" Alpha clors:"+times[3]/cnt);
}
else if(cnt>0xFFFFFFF)
{
cnt=0;
times[0]=0;
times[1]=0;
times[2]=0;
times[3]=0;
}
Paint p=new Paint();
p.setColor(0xFF0000FF);
g.drawLine(0, 420, Game.width, 420, p);
g.drawLine(0, 20, Game.width-20, Game.height, p);
g.drawText("hello", 50, 50, p);
blServiceDraw=false;
}
二,往Bitmap裡畫圖。
通過如下的方式來實現向Bitmap畫圖
if(bufferBitMap==null)
bufferBitMap=Bitmap.createBitmap(Game.width, Game.height, Bitmap.Config.ARGB_8888);
g=new Canvas(bufferBitMap);
可以建立一個mutable的bitmap,然後得到它的畫柄Canvas,
就可以往Bitmap裡畫圖
我在模擬器上測序了4種向ARGB_8888格式的Bitmap裡畫320X480圖的效能:
首先,畫inmutable的bitmap圖最快。(5毫秒)
注意:它比向View直接畫inmutable的bitmap圖(9毫秒)快很多,快了4秒
其次,畫mutable的bitmap圖比較慢。(11毫秒)
注意:它比向View裡直接畫mutable的bitmap圖(19毫秒)快很多,快了8秒
再其次,畫Alpha的RGB資料更慢。(39毫秒)
注意:它居然比向View裡直接畫Alpha的RGB資料(43毫秒)快
但是它仍然比向View裡直接畫非Alpha的RGB資料(34毫秒)慢
最後,畫非Alpha的RGB資料最慢。(47毫秒)
注意:它的表現太差了。它比向View裡直接畫Alpha的RGB資料(43毫秒)都要慢。
為什麼在往Bitmap裡畫非Alpha的RGB的資料還要慢呢?
Puzzle!
測試代碼2:
long times[]=new long[4];
int cnt=0;
Bitmap bufferBitMap;
protected void onDraw (Canvas g)
{
long time=System.currentTimeMillis();
Canvas gg=g;
if(bufferBitMap==null)
bufferBitMap=Bitmap.createBitmap(Game.width, Game.height, Bitmap.Config.ARGB_8888);
g=new Canvas(bufferBitMap);
if(img!=null)
{
boolean hasAlpha=!true;
time=System.currentTimeMillis();
g.drawBitmap(img.getBitMap(), 0, 0, null);
time=(System.currentTimeMillis()-time);
times[0]+=time;
int [] colors=new int [Game.width*Game.height];
for(int i=0;i<colors.length;i++)
colors=0xFF0000FF;
Bitmap bitMap=Bitmap.createBitmap(colors, Game.width, Game.height, Bitmap.Config.ARGB_8888);
time=System.currentTimeMillis();
g.drawBitmap(bitMap, 0, 0, null);
time=(System.currentTimeMillis()-time);
times[1]+=time;
time=System.currentTimeMillis();
hasAlpha=false;
g.drawBitmap(colors, 0, Game.width, 0, 0, Game.width, Game.height, hasAlpha, null);
time=(System.currentTimeMillis()-time);
times[2]+=time;
time=System.currentTimeMillis();
for(int i=0;i<colors.length;i++)
colors=0xF0000FFF;
hasAlpha=true;
time=System.currentTimeMillis();
g.drawBitmap(colors, 0, Game.width, 0, 0, Game.width, Game.height, hasAlpha, null);
time=(System.currentTimeMillis()-time);
times[3]+=time;
cnt++;
}
if(cnt%10==0)
{
System.out.println("run cnt:"+cnt);
System.out.println("time for mutable bitmap:"+times[0]
+" inmutable bitmap:"+times[1]
+" no alpha colors:"+times[2]
+" Alpha clors:"+times[3]);
System.out.println("average time for mutable:"+times[0]/cnt
+" inmutable:"+times[1]/cnt
+" no alpha colors:"+times[2]/cnt
+" Alpha clors:"+times[3]/cnt);
}
else if(cnt>0xFFFFFFF)
{
cnt=0;
times[0]=0;
times[1]=0;
times[2]=0;
times[3]=0;
}
g=gg;
Paint p=new Paint();
p.setColor(0xFF0000FF);
g.drawLine(0, 420, Game.width, 420, p);
g.drawLine(0, 20, Game.width-20, Game.height, p);
g.drawText("hello", 50, 50, p);
blServiceDraw=false;
}
如是把測試代碼2中的ARGB_8888格式改為RGB_565格式,得出以下結論:
首先,畫inmutable的bitmap圖最快。(9毫秒)
注意:它和向View直接畫inmutable的bitmap圖(9毫秒)一樣,
但是它比用ARGB_8888格式的(5毫秒)慢。
其次,畫mutable的bitmap圖比較慢。(11毫秒)
注意:它比向View裡直接畫mutable的bitmap圖(19毫秒)快,
它和用ARGB_8888格式的一樣快。
再其次,畫非Alpha的RGB資料更慢。(34毫秒)
注意:它和向View裡直接畫非Alpha的RGB資料速度一樣
但是它比ARGB_8888(47毫秒)快
最後,畫Alpha的RGB資料最慢。(43毫秒)
注意:它和向View裡直接畫Alpha的RGB資料速度一樣, 但是它比ARGB_8888(39毫秒)慢
Android的fillRect速度很快(1毫秒)
Android的Canvas本身沒有提供fillRect函數但是它提供了個功能相近的函數。
public void drawColor (int color)
Fill the entire canvas' bitmap (restricted to the current clip) with the specified color, using srcover porterduff mode.
可以把它封裝到一個fillRect函數,以便調用。
public void fillRect(int x,int y,int w,int h)
{
g.clipRect(x, y, w, h);
g.drawColor(p.getColor());
g.clipRect(rect);
}