2010-11-22 119 views
6

垃圾收集器運行時,我的Android遊戲中偶爾會出現滯後現象。我跑DDMS,發現所有的內存被我的應用程序分配的是這一行:在不分配內存的情況下將整數轉換爲字符串

scoreString = String.valueOf(score); 

什麼是一個字符串整數轉換沒有分配任何記憶的最佳方式?

+0

聽起來你展示事情的方式有問題。如果垃圾回收器或者字符串分配真的打亂了你的遊戲,那麼你還有其他嚴重的問題要掩蓋。 – Falmarri 2010-11-22 02:31:43

+0

你能解釋一下嗎?垃圾收集器可能是Android遊戲中最常見的性能問題。此外,除了短時間(不到一秒),性能會很好,但速度會變慢。查看日誌輸出,這些滯後與垃圾收集一致。 – Computerish 2010-11-22 03:15:00

回答

12

分配要顯示爲分數的字符數組,並根據分數的每個數字使用0-9查找表(無論如何,此方便地映射到0基數組)。

編輯: 從你的分數提取數字:

 
12345 mod 10 = 5 
12345 mod 100 = 45/10 = 4.5 (floors to 4) 
12345 mod 1000 = 345/100 = 3.45 (floors to 3) 
12345 mod 10000 = 2345/1000 = 2.345 (floors to 2) 
12345 mod 100000 = 12345/10000 = 1.2345 (floors to 1) 

而且你會知道什麼分數字符數組的最大長度應根據任何你正在使用的得分存儲(即INT)

我建議反向填充這個數組並把它初始化所有的「0」,這樣你的分數會顯示如下

 
0000000000 
0000005127 
+0

這真的是唯一的方法嗎?鑑於所需的數學量,我不完全確定這是否比分配內存更快。這段代碼在一個被稱爲每秒多次的循環中。 – Computerish 2010-11-22 01:41:36

+1

當然,我懷疑它的數學比碰撞檢測和反應所需的數學要少,或者你的遊戲需要其他任何機制以便經常改變分數? – 2010-11-22 01:48:20

0

我只是在跑對於這個問題,如果GC在一幀內踢,它真的很明顯。我想出了這個解決方案。

如果向後填充緩衝區,則可以重複使用% 10/ 10

將一個數字附加到StringBuilder的工作實現,可能不是實現它的最佳方式,但它工作並不會導致分配。你也可以使用其它字符數組的值,而不是在這裏鑄造爲char和(ASCII碼「0」)增加48

private char[] sbBuffer = new char[20]; 
private void appendInt(StringBuilder sb, int num) { 
    int i,j; 
    i = sbBuffer.length - 1; 
    if (num == 0) { 
     j = sbBuffer.length - 1; 
     sbBuffer[j] = (char) 48; 
    } else { 
     if (num < 0) 
      sb.append('-'); 
     num = Math.abs(num); 
     while (num > 0) { 
      sbBuffer[i] = (char) (num % 10 + 48); 
      i--; 
      num /= 10; 
     } 
     j = i + 1; 
    } 

    sb.append(sbBuffer, j, sbBuffer.length - j); 

    /* clean up */ 
    for (i = j; i < sbBuffer.length; i++) 
     sbBuffer[i] = 0; 
}