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