While passing multiple pieces of string for logging, is it best to use varargs or string concatenation?
Logging will be disabled in production environment.
Considering below code,
public void log(int logLevel, String ... msg) {
if (logLevel >= currentLogLevel) {
for (String m : msg) {
// print the log to file
}
}
}
// calling
log(2, "text1", var1, "text2");
Vs.
public void log(int logLevel, String msg) {
if (logLevel >= currentLogLevel) {
// print the log to file
}
}
// calling
log(2, "text1" + var1 + "text2");
Which one performs well in both contexts (enabled/disabled)?
Since Java-8 there's a faster alternative using
Supplier<String>
:This is significantly faster than concatenation provided that you execute this line many times (first time it's slower as anonymous class should be created). Source: Aleksey Shipilëv talk on Joker'14 (PDF, check slides 26-28).
If you are using something like SLF4J, you can do parameterized log messages. Like this
Which also has benefits of not also having to wrap some of them in log level check
if(log.isDebugEnabled())
. See this faqNeither one of these performs particularly well. The varargs will perform better, because it doesn't do
String
concatenation, which is a significantly more expensive operation than array creation, but because you are usingString
varargs and notObject
varargs, thetoString()
method will have to be called on all objects even in production, which will be relatively expensive.However, not to fear! This is a solved problem. SLF4J (Simple Logging Facade for Java) has already figured out the very best way to do this for you. If you use an SLF4J implementation (the two most common are Log4J and Logback), you get to use parameterized logging arguments:
Notice that in the first and second case, it doesn't create the temporary array, method signatures exist to not create the array if it's not necessary in SLF4J. Here is the full documentation where you can see all the different method signatures
If you should decide to use
Logback
, you should know that the cost of a method invocation when logging is turned off is around 20 nanoseconds. Full discussion of Logback's performance: