为什么android的String.format狗慢?
我正在使用自定义绘制视图实现 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 运行时,我从虚拟机收到了大量分配/释放消息。
那么,为什么 String.format 看起来可以更快(至少在来自对象创建成本昂贵的其他编程语言时)却如此慢?
I was implementing a ListView activity with custom drawn views and had the following code:
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
....
canvas.drawText(String.format("%02d: %dx%d", position, w, h),
10, 15, cached_paint);
}
Pretty much nothing else in the onDraw method, so this was driving me mad as to why the scrolling was so poor. By chance I changed the drawText parameter to not use String.format and suddenly the scrolling was butter silk again. In fact, the following is practically the same yet performs well:
canvas.drawText("" + position + ": " + w + "x" + h,
10, 15, cached_paint);
I'm stunned. Why is the latter faster than calling String.format? I would expect the object concatenation generate more intermediate objects and in general trash performance, but I've found exactly the opposite. In fact, when running with String.format I was getting lots of allocation/deallocation messages from the vm.
So why is String.format so slow when it apparently could be faster (at least when coming from other programming languages where object creation is expensive)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
+
进行字符串连接不会生成大量中间对象;基本上是一个 StringBuffer 及其内部字符数组(如果容量不足,可能会重新分配)。哦,还有连接后的字符串。此外,使用
+
时,分析进入字符串的对象的数据类型的大部分工作都是在编译时完成的。对于 String.format,这是在运行时完成的。最重要的是,传递给 String.format 的每个基本类型都需要自动装箱,这确实会生成更多的对象。String concatenation with
+
doesn't generate a lot of intermediate objects; basically a StringBuffer and its internal character array (which might get reallocated if it runs out of capacity). Oh, and the String when it's through concatenating.Also, with
+
, most of the work of analyzing the data types of the objects going into the string is done at compile time. With String.format, that is done at run time. To top it off, every primitive type you pass to String.format needs to be autoboxed, which does generate a lot more objects.为什么?
因为它是用Java编写的。
%02d: %dx%d
不是 Java。每次都必须解析并执行规则。这些规则通过java.util.Formatter
。现在,可以通过用本机代码 (C/C++) 实现替换 String.format() 来优化它,但我认为 varargs 和 JNI 会变得混乱。
这是因为
String.format()
相当复杂并且是用 Java 实现的。Why?
Because it is written in Java.
%02d: %dx%d
is not Java. That has to be parsed every time and the rules executed every time. Those rules are executed in Java, viajava.util.Formatter
.Now,
String.format()
could be optimized by replacing it with a native code (C/C++) implementation, but I think varargs and JNI get messy.That would be because
String.format()
is rather complex and is implemented in Java.为了获得最佳性能,您可以从
java.text
包创建一个格式化程序并缓存它。为了获得更好的性能,您可以使用更快的字符串连接。但这是一种不同类型的优化,与这个问题无关。
To get the best performance, you can create a formatter from the
java.text
package and cache it.For even better performance, you can use faster string concatenation. But that's a different kind of optimization, and off topic for this question.