Метод Java getChars в классе Integer, почему он использует побитовые операции вместо арифметики c? - PullRequest
3 голосов
/ 28 мая 2020

Итак, я изучал исходный код класса *1002* (JDK 8) класса Integer, чтобы понять, как int преобразовать в String. Похоже, что для преобразования массива int в char используется частный метод пакета getChars (строка 433).

Хотя код не так уж и сложен для понимания, однако существует несколько строки кода, в которых используются операции побитового сдвига вместо простых арифметических c умножения / деления, например, следующие строки кода:

// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));

и

q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...

Я просто делаю не понимаю смысла этого, действительно ли это оптимизация и влияет ли это на время выполнения алгоритма?

Изменить:

Другими словами, так как компилятор делает это тип внутренней оптимизации, нужна ли эта оптимизация вручную?

Ответы [ 2 ]

3 голосов
/ 28 мая 2020

Я не знаю причину этого изменения c, и, если вы не найдете оригинального автора, вряд ли вы все равно найдете на него авторитетный ответ.

Но я хотел бы ответить на более широкий вопрос, который заключается в том, что много кода в библиотеке времени выполнения (java.* и многие внутренние пакеты) оптимизированы до степени, которая была бы очень необычной (и я осмелюсь сказать, безответственной) для применимо к "нормальному" коду приложения.

И это имеет в основном две причины:

  1. Это вызывается много и во многих различных средах. Оптимизация метода на вашем сервере, чтобы он занимал на 0,1% меньше процессорного времени, когда он выполняется всего 50 раз в день на 3 серверах каждый, не стоит затраченных на него усилий. Если, однако, вы можете сделать Integer.toString 0,1% быстрее для всех , кто когда-либо его выполнит, то это действительно может обернуться очень большим изменением.
  2. Если вы оптимизируете код своего приложения на конкретной c виртуальной машине, а затем обновление этой виртуальной машины до более новой версии может легко отменить оптимизацию, если компилятор решит оптимизировать иначе. С кодом в java.* это гораздо меньше проблем, потому что он всегда поставляется со средой выполнения, которая будет его запускать. Поэтому, если они вводят изменение компилятора, которое делает данную оптимизацию больше не оптимальной, они могут изменить код, чтобы он соответствовал этому.

tl; dr java.* код часто оптимизирован до безумной степени, потому что это того стоит, и они могут знать , что это действительно сработает.

2 голосов
/ 28 мая 2020

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...