Скорость выполнения операций с булевыми и байтовыми одномерными массивами в Java (Eclipse/Spring)

Рейтинг: 1Ответов: 1Опубликовано: 12.01.2023

Имеется большой и ресурсозатратный кусок кода, который в зависимости от исходных данных и мощности ПК может выполняться от минуты, до нескольких часов, так что вопрос оптимизации стоит чуть ли не на первом месте.

На данный момент оптимизирую небольшой кусок кода, который при некоторых условиях также может выполняться довольно длительно. И вот собственно пару вопросов

Есть одномерной массив, размерностью минимум в 3 элемента, и с неизвестным максимумом. Я пробовал использовать boolean и byte. Суть в том, что мне нужно просто заполнить этот массив нулями (false) и единицами (true). Так вот, подсчитывал время выполнения, и почти во всех случаях операции с булевским массивом выполнялись быстрее, чем с байтовым массивом, но байтовый массив понятное дело кушает меньше памяти.

В трех местах идет обращение к этому массиву:

byte[]:

if (array[i] == 0)            
   array[i] = 1;
...

if (array[j] == 1)
...

boolean[]:

if (!array[i])            
   array[i] = true;
...

if (array[j])
...

Почему операции c байтовым массивом выполняются медленнее булевого массива? У меня в среднем выходила разница в пределах 5-30%. Или это некий уровень "погрешности" из-за неидеальных условий сравнений? Как можно лучше оптимизировать обращение к такому массиву, чтобы затрачиваемое время и занимаемая память была минимальной?

И еще небольшой вопрос. Есть следующий кусок:

arr[i * 3] = 'что-то'
arr[i * 3 + 1] = 'что-то'
arr[i * 3 + 2] = 'что-то'

Опять же, как будет выгоднее по скорости и памяти? Подобная запись, или лучше стоит до обращения к массиву создать переменную int a = i * 3?

P.S. Неправильно указал вставки кода

for (int i = 0; i < indices.length; i++) {
    if (array[indices[i]] == 0)
        array[indices[i]] = 1;
}

Ответы

▲ 1

Возможно у вас не совсем корректные условия теста.
Нельзя подсчитывать время выполнения для таких быстрых операций на маленьких объемах. У вас погрешность измерения времени будет больше, чем время выполнения операций. Вероятнее всего, операции с byte и boolean выполняются за одинаковое время (или очень близкое).
По второму вопросу - скорее всего разницы нет. Оптимизатор достаточно умный и оба варианта приведет к одинаковому исполняемому коду.

При этом, на современных процессорах на быстродействие кода больше влияет - помещаются ли ваши данные в кэш процессора или нет - т.е. элементарные операции над массивом могут выполниться по времени быстрее, чем он прочтется из оперативной памяти в кэш данных.
Ещё момент - вот эта операция в контексте вашего вопроса не имеет смысла

if (array[i] == 0)            
   array[i] = 1;

// оставьте просто
array[i] = 1;

В случае boolean оптимизатор скорее всего такой код и сгенерит. А для byte - нет. Но вы-то знаете, что значения могут быть только 0/1. Вероятнее всего именно этим и обусловлена разница во времени между вашими вариантами.
В любом случае это надо проверять.
Ну и по такому маленькому отрывку кода тяжело сказать что-то более конкретное.