Почему у JVM есть коды операций iconst_2 - iconst_5?

Читая спецификацию JVM (как это делают), я был очень удивлен, когда наткнулся на 7 iconst_<i> опкоды. В конце концов, есть только один байт для игры.

Я очень редко пишу литералы для 2, 3, 4 или 5 в моем коде. Я могу понять, почему с -1, 0 и 1 можно обращаться особым образом, но мне кажется удивительным, что дизайнеры хотели бы использовать 4 драгоценных кода операции для чисел, которые оказались очень маленькими.

Кто-нибудь знает, есть ли для этого веская причина? Я недооцениваю выгоду от них?

2 ответа

Решение

Я думаю, ваше предположение верно: просто сделать байт-код меньше, а Java-интерпретатор чуть-чуть быстрее (в те времена не было JIT-компилятора). Обратите внимание, что эти байт-коды могут использоваться гораздо чаще, чем вы ожидаете. Например, рассмотрим следующий код:

int[] a = {10, 20, 30, 40};

По сути это скомпилировано в нечто вроде:

int[] a = new int[4];
a[0] = 10;
a[1] = 20;
a[2] = 30;
a[3] = 40;

Так вот iconst_0 в iconst_4 используются, даже если у вас нет таких констант в исходном коде.

Надеюсь, что это может прояснить ваш вопрос Зачем тратить 4 кода операции..

Посмотрите Байт-код этого кода

public static void main(String[] args) {
        int b = 20;
        int c = 5;
        int d= 6;
    }

часть байт-кода

0: bipush        20
 2: istore_1
 3: iconst_5
 4: istore_2
 5: bipush        6
 7: istore_3

Как вы можете видеть для номера больше 5, он начинает использовать bipushкоторые обычно менее эффективны, чем эквивалент iconst_<n> а также занять больше байтов в файле класса.

bipush byte1 раскрываться byte1 в int, а затем помещает его в стек, потому что каждый слот в стеке Java имеет ширину 32 бита (JVM - это виртуальные машины на основе стека)

И посмотреть, если bipushзанимает больше байта..

Посмотрите размер файла класса в двух следующих кодах (этот размер на моем 64-битном компьютере.. он может отличаться на вашем компьютере, но разница будет такой же)

public class Test2 {

    public static void main(String[] args) {
        int b = 5;

    }

}

размер 406 байт

сейчас, если я заменю b =6; размер файла того же класса становится 407 bytes который остается постоянным, даже когда b=127 который также использует bipush, Это различие в размере связано с тем, что bipush имеет 2 байта, один байтовый код операции, второе байтовое значение constat.

формат bipush:

bipush
byte

как вы можете видеть из строки 5: bipush 6 в байт-коде в то время как iconst_<n> использует только 1 байт.

Таким образом, такие байт-коды определены для некоторых обычно выдвигаемых чисел, чтобы повысить эффективность выполнения байт-кода и уменьшить размер потоков байт-кода.

и, как сказал Тагир, эти цифры будут использоваться чаще, чем вы думаете

Другие вопросы по тегам