Я пишу код довольно низкого уровня, который должен быть сильно оптимизирован для скорости. Каждый цикл процессора имеет значение. Поскольку код написан на Java, я не могу писать на таком же низком уровне, как, например, на C, но я хочу извлечь из ВМ все, что могу.
Я обрабатываю массив байтов. В настоящий момент меня интересуют две части моего кода. Первый из них:
int key = (data[i] & 0xff)
| ((data[i + 1] & 0xff) << 8)
| ((data[i + 2] & 0xff) << 16)
| ((data[i + 3] & 0xff) << 24);
а второй:
key = (key << 15) | (key >>> 17);
Судя по производительности, я предполагаю, что эти заявления не оптимизированы так, как я ожидаю. Второе утверждение в основном ROTL 15, key
. Первый оператор загружает 4 байта в int. Маски 0xff
предназначены только для компенсации добавленных знаковых битов, возникающих в результате неявного преобразования типа int, если получаемый байт оказывается отрицательным. Это должно быть легко перевести на эффективный машинный код, но, к моему удивлению, производительность возрастет, если я сниму маски. (Что, конечно, нарушает мой код, но мне было интересно посмотреть, что произойдет.)
Что здесь происходит? Оптимизируют ли наиболее распространенные виртуальные машины Java этот код во время JIT так, как можно ожидать, что хороший компилятор C ++ оптимизирует эквивалентный код C ++? Могу ли я повлиять на этот процесс? Установка -XX:+AggressiveOpts
, кажется, не имеет значения.
(ЦП: x64, платформа: Linux / HotSpot)