Я просто наткнулся на странную вещь во время кодирования на Java:
Я читаю файл в bytearray (byte[] file_bytes
), и мне нужен вывод hexdump (например, утилиты hexdump
или xxd
в Linux). В основном это работает (см. For-loop-code, который не закомментирован), но для больших файлов (> 100 КиБ) требуется немного, чтобы пройти через байтовые массивы, сделать правильное форматирование, и так далее.
Но если я поменяю код цикла for на код, который является закомментированным (используя класс с тем же кодом цикла for для вычисления!), Он будет работать очень быстро.
В чем причина такого поведения?
Codesnippet:
[...]
long counter = 1;
int chunk_size = 512;
int chunk_count = (int) Math.ceil((double) file_bytes.length / chunk_size);
for (int i = 0; i < chunk_count; i++) {
byte[] chunk = Arrays.copyOfRange(file_bytes, i * chunk_size, (i + 1) * chunk_size);
// this commented two lines calculate way more faster than the for loop below, even though the calculation algorithm is the same!
/*
* String test = new BytesToHexstring(chunk).getHexstring();
* hex_string = hex_string.concat(test);
*/
for (byte b : chunk) {
if( (counter % 4) != 0 ){
hex_string = hex_string.concat(String.format("%02X ", b));
} else{
hex_string = hex_string.concat(String.format("%02X\n", b));
}
counter++;
}
}
[...]
класс BytesToHexstring:
class BytesToHexstring {
private String m_hexstring;
public BytesToHexstringTask(byte[] ba) {
m_hexstring = "";
m_hexstring = bytes_to_hex_string(ba);
}
private String bytes_to_hex_string(byte[] ba) {
String hexstring = "";
int counter = 1;
// same calculation algorithm like in the codesnippet above!
for (byte b : ba) {
if ((counter % 4) != 0) {
hexstring = hexstring.concat(String.format("%02X ", b));
} else {
hexstring = hexstring.concat(String.format("%02X\n", b));
}
counter++;
}
return hexstring;
}
public String getHexstring() {
return m_hexstring;
}
}
Строка hex_string:
00 11 22 33
44 55 66 77
88 99 AA BB
CC DD EE FF
Тесты:
file_bytes.length = 102400 байт = 100 КиБ
- через класс: ~ 0,7 с
- без класса: ~ 5,2 сек
file_bytes.length = 256000 байт = 250 КиБ
- через класс: ~ 1,2 сек
- без класса: ~ 36 с