3

我有以下代码用于将字节数组编码为 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 上测试

4

3 回答 3

1

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

从这里开始,如果你需要更多,你只需要在你的硬件上进行 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 等。

于 2013-04-27T15:07:58.510 回答
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];
}

ps

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

于 2013-04-27T14:29:35.897 回答
0

这是另一个建议:

public static void writeHexBytes(byte[] data, StringBuilder sb) {
    for (byte b : data) {
        sb.append(String.format("%02X", b));
    }
}
于 2013-04-27T14:55:22.930 回答