为什么这段代码很慢?

时间:2013-04-27 13:18:21

标签: java android performance

我有以下代码用于将字节数组编码为HEX字符串

private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
public static void WriteHexBytes(byte[] data, StringBuilder sb)
{
    char[] chars = new char[data.length*2];
    for (int i = 0; i < data.length; ++i)
    {
        chars[2*i] = HEX_CHARS[(data[i] & 0xF0) >>> 4];
        chars[2*i + 1] = HEX_CHARS[data[i] & 0x0F];
    }
    sb.append(chars);
}

for循环非常慢,在实际设备上编码10 seconds个字节需要3MB。在模拟器上它需要永远。 sb.append即时执行。

这是正常的吗?这对我来说似乎很慢?什么导致缓慢?

在三星Galaxy Tab 2 7.0上测试

3 个答案:

答案 0 :(得分:1)

从Java的角度来看,有一种比你所展示的方法更快的方法并不明显。 Apache Common's code看起来比你的略好,但这只是一个模糊的猜测。

从这里开始,如果你需要更多,你只需要硬件上的Microbenchmark,我担心:(。

只是出于懒散......我做了微观基准(临时,不科学)你的解决方案和我刚刚做过的 - 你赢了两倍。这是我试过的:

public static void niko(byte[] data, StringBuilder sb)
{
    for (byte element : data) {
        sb.append(toChar((element & 0xf0) >>> 4));
        sb.append(toChar(element & 0x0f));
    }
}

static char toChar(int b) {
    int offset = b < 10 ? 48 : 87;
    return (char) (b + offset);
}

通过10 MB 100次,你的代码在4秒内完成,8代完成。但请记住,这是非常依赖硬件的,JVM依赖的等等。

答案 1 :(得分:0)

我更喜欢把它写成评论(无法尝试这是否会对Android产生影响),但我无法在评论中编写格式化代码......: - /

您可以尝试缓存一些值以避免一些调用:

int len = data.length;
char[] chars = new char[len * 2];
for (int i = 0; i < len; ++i) {
    int b = data[i] & 0xff;
    chars[2*i] = HEX_CHARS[b >>> 4];
    chars[2*i + 1] = HEX_CHARS[b & 0x0F];
}

P.S。

如果返回一个String而不是写入StringBuilder就可以了,你也可以尝试写一个字节数组而不是一个char数组来减少分配的内存大小,然后从字节数组中构造字符串。

答案 2 :(得分:0)

这是另一个建议:

public static void writeHexBytes(byte[] data, StringBuilder sb) {
    for (byte b : data) {
        sb.append(String.format("%02X", b));
    }
}