我正在用java编写一个模拟重力的程序,在其中我有一堆日志语句(到System.out)。我的程序运行速度很慢,我认为日志记录可能是其中一部分原因。有没有办法禁用System.out,以便我的程序在打印时不会变慢,或者我是否必须手动浏览并注释/取消注释每个程序以启用/禁用调试语句?任何帮助,将不胜感激。
答案 0 :(得分:15)
输出流gobbler再次起作用,可能就像......
System.setOut(new PrintStream(new OutputStream() {
@Override
public void write(int arg0) throws IOException {
}
}));
但更好的解决方案是使用已经提到的正式日志记录实用程序。
答案 1 :(得分:12)
您应该使用真实的日志记录框架,例如log4j或slf4j。在任何一种情况下,您都可以设置日志记录级别,以限制转储到日志中的信息级别。
如果您坚持使用System.out,则可以将日志记录语句包装在一个条件中,例如
if (DEBUG) {
System.out.println(...);
}
是的,对System.out进行大量日志记录或打印会影响性能。
答案 2 :(得分:4)
我同意其他人应该使用合适的记录器。然而,在每种情况下都不可能。 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; }
});
我的样本测量结果如下:
write(int)
OutputStream
的57毫秒
PrintStream
方法println
和printf
用法时,所以它比其他答案更快,但不能打败不存在的代码(注释System.out
或包装if (DEBUG)
),因为varargs分配数组和框原语或{{1 (StringBuilder
)仍然执行。
答案 3 :(得分:3)
绝对开始使用日志API而不是System.out
。我强烈推荐Logback。您可以轻松设置只记录到控制台的内容,但可以随时关闭。 Logback很容易配置,但是如果你不喜欢配置文件,你甚至可以通过编程方式设置它。
Log4j也很好,它是与Logback相同的作者的早期框架,被许多人认为是标准。 SLF4J,同一作者再一次,不是真正的日志框架,而是抽象实际日志记录实现的标准包装器。 Log4j可以包装在SLF4J中,而Logback具有本机SLF4J接口。如果我是你,我会为various reasons避免使用Apache Commons Logging。我从未成为内置Java日志记录的忠实粉丝(java.util.logging
)。
答案 4 :(得分:2)
如果你不介意只通过一次,你可以创建一个“启用”或“禁用”的常量,并添加一个标志,只有在启用该常量时才打印。然后你可以轻松地翻转常数。
public static boolean PRINTLN_ENABLED = true;
if(Constant.PRINTLN_ENABLED)
System.out.println();
答案 5 :(得分:2)
我建议您将来查看log4j(或类似的库)。它的工作方式与system.out相同,但实际上有可以在需要时关闭它们。
答案 6 :(得分:2)
如果您的应用程序是在命令行启动的,则可以在操作系统级别禁用整个程序的stdout流。这将有效地禁用所有System.out.prinln(),而无需您更改任何代码。
在Linux / Unix上,您可以通过将stdout重定向到/ dev / null来关闭它:java MyJavaProgram > /dev/null
答案 7 :(得分:1)
由于您在其中一条评论中提到了Eclipse,因此您可以在此处找到相关答案:https://stackoverflow.com/a/799277/1017130
(我最初想发布这个作为对shj答案的评论,但似乎我需要更多的代表)
最好的长期解决方案是使用日志框架。我通常使用内置日志记录,因为我试图避免额外的依赖。您可以在此处详细了解:http://docs.oracle.com/javase/1.4.2/docs/guide/util/logging/overview.html
答案 8 :(得分:0)
我怀疑你可以使用System.setOut(PrintStream)
委托一个没有做任何事情的PrintStream
,但这可能不会消除你所有的开销 - 我怀疑,例如,格式化错误消息仍然会花费你。
答案 9 :(得分:0)
我已将此代码放入我的Web项目中的查找侦听器中并解决了问题
/*
* 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) {}
} );
}
}