Будет ли оптимизатор Java удалять конструкцию параметров для пустых вызовов методов? - PullRequest
2 голосов
/ 22 июня 2010

Предположим, у меня есть такой код:

log.info("Now the amount" + amount + " seems a bit high")

и я бы заменил метод log на фиктивную реализацию вроде:

class Logger {
   ...
   public void info() {}

}

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

Ответы [ 2 ]

3 голосов
/ 22 июня 2010

Я бы предположил, что компилятор (javac) этого не сделает, но вполне вероятно, что компилятор точно вовремя.

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

Чтобы быть уверенным, сделайте небольшой тест, который сравнивает это с кодом, предложенным Джеспером, и посмотрите, что из этогобыстрее или если они одинаково быстры.

Также см. здесь: http://www.ibm.com/developerworks/java/library/j-jtp12214/index.html#3.0

1 голос
/ 22 июня 2010

Важный ответ: это может сделать .

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

Проблема с положением в оптимизатор заключается в том, что вы настраиваете себя на выполнение невидимого контракта, о котором вы даже не подозреваете. Hotspot будет работать по-разному в других версиях JDK / JRE, поэтому нет гарантии, что, если он будет работать на вашей конкретной JVM, он будет работать в другом месте. Но помимо этого, точная оптимизация, которая имеет место , может , зависит от таких экологических факторов, как количество свободной кучи, количество ядер на машине и т. Д.

И даже если вам удастся подтвердить, что в вашей ситуации это работает нормально, вы просто сделали свою кодовую базу невероятно нестабильной. Я точно знаю, что одна из оптимизаций / вложений, которые выполняет Hotspot, зависит от количества загруженных и используемых подклассов для неконечного класса. Если вы начнете использовать другую библиотеку / модуль, который загружает вторую реализацию log - BANG, оптимизация закручивается и производительность снова становится ужасной. И удачи вам в том, что добавление сторонней библиотеки в ваш classpath повышает внутреннюю производительность вашего приложения ...


Во всяком случае, я не думаю, что вы задаете настоящий вопрос. В случае, который вы описали, лучшим решением будет не изменить реализацию метода info, а изменить вызовы на no-ops (т.е. закомментировать их). Если вы хотите сделать это сразу для нескольких классов, во время компиляции , вы можете использовать тип IFDEF, например:

public class Log
{
    public static final boolean USE_INFO = true;

    public void info()
    {
       ...
    }

    ...
}

и затем в вашем классе:

if (Log.USE_INFO)
{
    log.info("Now the amount" + amount + " seems a bit high");
}   

Теперь компилятор (javac, а не Hotspot) может видеть, что логическое условие является постоянным, и исключает его при компиляции. Если вы установите логический флаг в false и перекомпилируете, тогда все операторы info будут полностью удалены из файла, так как javac может сказать, что они никогда не будут вызваны.

Если вы хотите иметь возможность включать / отключать ведение журнала информации во время выполнения, тогда вместо постоянного логического флага вам нужно будет использовать метод, и здесь нет ничего, кроме того, чтобы каждый раз вызывать метод. В зависимости от реализации метода, Hotspot может быть в состоянии оптимизировать проверку, но, как я упоминал выше, не рассчитывайте на нее.

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