【问题标题】:Why is android's String.format dog slow?为什么android的String.format狗慢?
【发布时间】:2011-09-12 18:52:43
【问题描述】:

我正在使用自定义绘制的视图实现一个 ListView 活动,并具有以下代码:

@Override
public void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
    ....
    canvas.drawText(String.format("%02d: %dx%d", position, w, h),
        10, 15, cached_paint);
}

onDraw 方法中几乎没有其他内容,所以这让我很生气,为什么滚动效果如此之差。偶然我将drawText参数更改为不使用String.format,突然滚动又变成了黄油丝。事实上,以下内容几乎相同,但表现良好:

canvas.drawText("" + position + ": " + w + "x" + h,
    10, 15, cached_paint);

我惊呆了。为什么后者比调用 String.format 更快?我希望对象连接会产生更多的中间对象和一般的垃圾性能,但我发现恰恰相反。事实上,当使用 String.format 运行时,我从 vm 收到了很多分配/解除分配消息。

那么为什么 String.format 显然可以更快(至少来自其他创建对象昂贵的编程语言时)却如此慢?

【问题讨论】:

    标签: android performance string listview format


    【解决方案1】:

    + 的字符串连接不会产生很多中间对象;基本上是一个 StringBuffer 及其内部字符数组(如果容量不足,可能会重新分配)。哦,还有通过连接的字符串。

    另外,对于+,分析进入字符串的对象的数据类型的大部分工作都是在编译时完成的。使用 String.format,这是在运行时完成的。最重要的是,您传递给 String.format 的每个原始类型都需要自动装箱,这确实会生成更多对象。

    【讨论】:

      【解决方案2】:

      我惊呆了。

      为什么?

      为什么后者比调用 String.format 更快?

      因为它是用 Java 编写的。 %02d: %dx%d 不是 Java。每次都必须对其进行解析,并且每次都必须执行规则。这些规则在 Java 中通过java.util.Formatter 执行。

      现在,String.format() 可以通过用本机代码 (C/C++) 实现替换它来进行优化,但我认为 varargs 和 JNI 会变得混乱。

      我希望对象连接会产生更多的中间对象和一般的垃圾性能,但我发现恰恰相反。事实上,当使用 String.format 运行时,我从 vm 收到了很多分配/解除分配消息。

      那是因为String.format() 相当复杂,并且是用 Java 实现的。

      【讨论】:

      • 对,只是阅读一些关于java中可变参数的性能提示:不要使用它们。
      【解决方案3】:

      为了获得最佳性能,您可以从 java.text 包创建格式化程序并将其缓存。

      final static DecimalFormat myFormat = new DecimalFormat("###");
      @Override
      public void onDraw(Canvas canvas)
      {
          super.onDraw(canvas);
          ....
          canvas.drawText(myFormat.format(w) + "x" + myFormat(h));
      }
      

      为了获得更好的性能,您可以使用更快的字符串连接。但这是一种不同类型的优化,与本问题无关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-07
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 2011-06-07
        • 2016-04-19
        相关资源
        最近更新 更多