Статьи

Низкий уровень Java: преобразование целых чисел в текст (часть 1)

Поскольку у Java есть несколько способов преобразовать целое число в строку, это не то, что вы могли бы написать самостоятельно.

Однако могут возникнуть ситуации, когда вы захотите это сделать. Одним из них является, когда производительность является цирковой. Библиотеки Java, как правило, создают больше объектов, чем требуется. Обычно это не имеет значения, но бывают случаи, когда вам нужно, чтобы система работала быстрее, и чтение и запись чисел являются для вас большим успехом.

Разница в производительности

Нижеследующее основано на неоднократных проверках целых чисел 128 КБ в двоичном и текстовом форматах, что занимает среднее время для записи и чтения целого числа.

Источник для запуска всех тестов

Источник для примеров

Unsafe text: Typically took 41.4 ns to write/read per long.
ByteBuffer direct text: Typically took 63.9 ns to write/read per long.
ByteBuffer heap text: Typically took 68.9 ns to write/read per long.
Print text: Typically took 325.7 ns to write/read per long.
DecimalFormat text: Typically took 645.5 ns to write/read per long.

Unsafe binary: Typically took 4.2 ns to write/read per long.
ByteBuffer binary: Typically took 10.3 ns to write/read per long.
DataStream binary: Typically took 72.1 ns to write/read per long.

В этом тесте чтение / запись целых чисел в виде текста с использованием разных подходов варьируется в целых 14 раз. Если ваш целочисленный формат необходимо настроить, вам может понадобиться использовать DecimalFormat или написать свой собственный.

Примечание: более быстрые опции для записи / чтения текста были быстрее, чем при использовании двоичного DataInput / OutputStream. Поток устраивает
длинный , как 8 байт в
большом обратном порядке байт порядка, больше работы , чем преобразование числа в текст в этих случаях.

Запись целого числа в текст

В этом примере все целые числа обрабатываются как
тип
long . Есть небольшое преимущество в производительности, если
вместо этого использовать тип
int, но оно относительно небольшое.

Целочисленное представление

Все целые числа,
байт ,
короткие ,
ИНТ и
долго представлены в виде
двойки-комплемента кодирование / декодирование этого формата не требует каких — либо битовые операции , как числа с плавающей точкой может в.

Извлечь знак

Сначала извлеките знак. Это просто сделать,

извлекая знак

if (num < 0) {
   writeByte('-');
   num = -num;
}

Здесь есть один крайний случай — Long.MIN_VALUE. Из-за представления с двумя дополнениями это значение само по себе отрицательно. Один из способов обработки этого значения — специально его кодировать. Например, есть константа, которая содержит то, что должно быть закодировано. Другой подход — рассматривать Long.MIN_VALUE как неустановленное значение или NaN. В большинстве приложений для работы с электронными таблицами пустое поле рассматривается как неустановленная ячейка. (Это мое предпочтение) Еще одно особое значение — ноль. Другие числа не имеют начального нуля, но для нуля должна быть хотя бы одна цифра.

Обработка 0

if (num == 0) {
    writeByte('0');
    writeByte(SEPARATOR);
} else {

Написание цифр

Может быть проще декодировать число с конца. Это подход, который я выбрал здесь.

Запись каждой цифры в обратном порядке

// find the number of digits
int digits = ParserUtils.digits(num);
// starting from the end, write each digit
for (int i = digits - 1; i >= 0; i--) {
    // write the lowest digit.
    buffer.put(buffer.position() + i, (byte) (num % 10 + '0'));
    // remove that digit.
    num /= 10;
}
// move the position to after the digits.
buffer.position(buffer.position() + digits);
writeByte(SEPARATOR);

От http://vanillajava.blogspot.com/2011/07/java-low-level-converting-between.html