【问题标题】:Convert an integer to a string without allocating memory将整数转换为字符串而不分配内存
【发布时间】:2010-11-22 01:12:30
【问题描述】:

当垃圾收集器运行时,我的 Android 游戏偶尔会出现延迟。我运行了 DDMS,发现我的应用程序分配的所有内存都来自这一行:

scoreString = String.valueOf(score);

在不分配任何内存的情况下将整数转换为字符串的最佳方法是什么?

【问题讨论】:

  • 听起来您显示事物的方式是这里的问题。如果垃圾收集器或字符串分配确实扰乱了您的游戏,那么您还有其他要掩盖的严重问题。
  • 你能解释一下吗?垃圾收集器可能是 Android 游戏中最常见的性能问题。另外,性能很好,除了速度变慢的短暂时间(不到一秒)。查看日志输出,这些滞后与垃圾收集一致。

标签: java android memory-management


【解决方案1】:

分配要显示为分数的字符数组,并使用 0-9 的查找表(这很方便地映射到以 0 为基数的数组)根据分数的每个数字附加到该数组。

编辑: 从分数中提取数字:

12345 模 10 = 5 12345 mod 100 = 45 / 10 = 4.5(至 4 层) 12345 mod 1000 = 345 / 100 = 3.45(至 3 层) 12345 mod 10000 = 2345 / 1000 = 2.345(至 2 层) 12345 mod 100000 = 12345 / 10000 = 1.2345(1楼)

您还将知道分数字符数组的最大长度应基于您用于存储分数的任何内容(即 int)

我建议反向填充此数组并将其初始化为全“0”,这样您的分数就会显示为

0000000000 0000005127

【讨论】:

  • 真的只有这样吗?考虑到所需的数学量,我不完全确定这是否比分配内存更快。此代码处于每秒被多次调用的循环中。
  • 当然,我怀疑它比碰撞检测和响应所需的数学或游戏需要的任何其他机制来使分数经常变化?
【解决方案2】:

我也遇到了这个问题,如果 GC 在一帧中启动,那真的很明显。我想出了这个解决方案。

如果你向后填充缓冲区,你可以重复% 10/ 10

将数字附加到 StringBuilder 的工作实现,可能不是最好的方法,但它可以工作并且不会导致分配。您也可以使用另一个字符数组作为值,而不是转换为 char 并添加 48(ascii 中的“0”)

    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;
}

【讨论】:

    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    相关资源
    最近更新 更多