Как избежать кода операции getfield - PullRequest
29 голосов
/ 21 января 2011

В Java-классе String метод trim содержит следующее:

int off = offset;      /* avoid getfield opcode */
char[] val = value;    /* avoid getfield opcode */

Я немного озадачен комментарием "избежать кода операции getfield" ...

Что это значит?(Я так понимаю, это позволяет избежать использования getfield в байт-коде, но почему это хорошая вещь [TM]?)

Это предотвращает создание объектов в случае trim ничего не делает (и, следовательно, этот возвращается) или?

Ответы [ 2 ]

22 голосов
/ 21 января 2011

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

Конечно, возникает вопрос о том, почему тот же комментарий не был применен к локальной переменной len. (Я также ожидал бы, что JIT все равно будет избегать повторной загрузки, особенно когда переменные являются окончательными.)

14 голосов
/ 21 января 2011

getfield используется для получения переменной-члена класса.

Как видно из оставшегося кода:

while ((st < len) && (val[off + st] <= ' ')) {
    st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
    len--;
}

Поэтому, когда вы находитесь в цикле, он должен выполнять getfield каждый раз, когда вы ссылаетесь на value или offset. Вы можете получить значительный удар по производительности, если цикл выполняется в течение длительного времени (поскольку каждый раз, когда проверяется условие цикла, getfield создается для offset и value). Таким образом, используя локальные переменные off и val, вы снижаете снижение производительности.

...