Подтвердить что ты не робот

Отключить System.out для скорости в Java

Я пишу программу в java, которая имитирует гравитацию, и в ней у меня есть множество операторов журнала (для System.out). Моя программа работает очень медленно, и я думаю, что регистрация может быть частью причины. Есть ли способ отключить System.out, чтобы моя программа не замедлялась при печати, или мне приходится вручную проходить и комментировать/раскомментировать каждый, чтобы включить/отключить отладочные заявления? Любая помощь будет оценена по достоинству.

4b9b3361

Ответ 1

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

System.setOut(new java.io.PrintStream(new java.io.OutputStream() {
    @Override public void write(int b) {}
}) {
    @Override public void flush() {}
    @Override public void close() {}
    @Override public void write(int b) {}
    @Override public void write(byte[] b) {}
    @Override public void write(byte[] buf, int off, int len) {}
    @Override public void print(boolean b) {}
    @Override public void print(char c) {}
    @Override public void print(int i) {}
    @Override public void print(long l) {}
    @Override public void print(float f) {}
    @Override public void print(double d) {}
    @Override public void print(char[] s) {}
    @Override public void print(String s) {}
    @Override public void print(Object obj) {}
    @Override public void println() {}
    @Override public void println(boolean x) {}
    @Override public void println(char x) {}
    @Override public void println(int x) {}
    @Override public void println(long x) {}
    @Override public void println(float x) {}
    @Override public void println(double x) {}
    @Override public void println(char[] x) {}
    @Override public void println(String x) {}
    @Override public void println(Object x) {}
    @Override public java.io.PrintStream printf(String format, Object... args) { return this; }
    @Override public java.io.PrintStream printf(java.util.Locale l, String format, Object... args) { return this; }
    @Override public java.io.PrintStream format(String format, Object... args) { return this; }
    @Override public java.io.PrintStream format(java.util.Locale l, String format, Object... args) { return this; }
    @Override public java.io.PrintStream append(CharSequence csq) { return this; }
    @Override public java.io.PrintStream append(CharSequence csq, int start, int end) { return this; }
    @Override public java.io.PrintStream append(char c) { return this; }
});

Мои измерения были:

  • Вывод 82 мс с полным выводом
  • 57ms, когда только переопределение write(int) в OutputStream
  • 31 мс при переопределении методов PrintStream
  • 5ms при комментировании всех println и printf обычаев

Таким образом, он быстрее, чем другие ответы здесь, но не может бить несуществующий код (комментируя System.out или обертывая в if (DEBUG)), поскольку varargs выделяет примитивы массивов и ящиков или StringBuilder (+ тоже ) все еще выполняется.

Ответ 2

Снова может работать гоблер выходного потока, что-то вроде...

System.setOut(new PrintStream(new OutputStream() {
    @Override
    public void write(int arg0) throws IOException {

    }
}));

Но лучшим решением является использование формальной утилиты регистрации, как уже упоминалось.

Ответ 3

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

если вы настаиваете на использовании System.out, вы можете обернуть ваши протоколирующие заявления в состояние, например,

if (DEBUG) {
  System.out.println(...);
}

и да, тяжелая регистрация или печать на System.out повлияют на производительность.

Ответ 4

Определенно начните использовать API протоколирования вместо System.out. Я настоятельно рекомендую Logback. Вы можете легко настроить что-то, что просто входит в консоль, но может быть отключено в любое время. Резервное копирование мертво просто для настройки, но если вам не нравятся конфигурационные файлы, вы можете даже установить это программно.

Log4j также хорошо, это ранняя структура того же автора, что и Logback, и многие считают, что это стандарт, SLF4J, еще раз тем же автором, это не настоящая структура ведения журнала, а скорее стандартная оболочка для абстрактной реализации фактического ведения журнала. Log4j можно обернуть в SLF4J, а Logback имеет собственный интерфейс SLF4J. Если бы я был вами, я бы избежал регистрации Apache Commons Logging, для различных причин. Я никогда не был большим поклонником встроенного журналирования Java (java.util.logging).

Ответ 5

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

public static boolean PRINTLN_ENABLED = true;

if(Constant.PRINTLN_ENABLED)
    System.out.println();

Ответ 6

Я бы предположил, что вы заглянете в log4j (или подобные библиотеки) в будущем. Он работает так же, как и system.out, но на самом деле есть переключатели, чтобы отключить их, когда вам нужно.

Ответ 7

Если ваше приложение запущено в командной строке, вы можете отключить поток stdout для всей программы на уровне ОС. Это фактически отключит все ваши System.out.prinln() s, не требуя от вас изменения какого-либо кода.

В Linux/Unix вы можете закрыть stdout, перенаправив его в /dev/null: java MyJavaProgram > /dev/null

Ответ 8

Поскольку вы упомянули Eclipse в одном из своих комментариев, вы можете найти соответствующий ответ здесь: fooobar.com/questions/437157/...

(Я изначально хотел опубликовать это как комментарий к shj answer, но мне кажется, что мне нужно больше повторить сначала)

Лучшим долгосрочным решением будет использование рамки ведения журнала. Обычно я использую встроенное ведение журнала, так как я стараюсь избегать дополнительных зависимостей. Подробнее об этом можно прочитать здесь: http://docs.oracle.com/javase/1.4.2/docs/guide/util/logging/overview.html

Ответ 9

Я подозреваю, что вы можете использовать System.setOut(PrintStream) для делегирования PrintStream, который ничего не делает, но это, вероятно, не будет устранить все ваши накладные расходы - я подозреваю, например, что форматирование сообщений об ошибках по-прежнему будет стоить вам.

Ответ 10

Я поставил этот код один раз в поисковый прослушиватель в моем веб-проекте и решил проблему

  /*
     * In this case, if you are not in debug mode or any other 
     *the default system out is replaced internally with this
     *implementation, else it works as expected. This way you do not 
     *have to find and replace anything in your code.
     */
//or as i did servletContext.getInitParameter("mode") 
//from web.xml for global parameter

        if(!DEBUG) {
        System.setOut(
            new PrintStream(new OutputStream() { 
                public  void    close() {}
                public  void    flush() {}
                public  void    write(byte[] b) {}
                public  void    write(byte[] b, int off, int len) {}
                public  void    write(int b) {}

            } );
        }
    }