1

I want to print out my app's workflow. I'd like to know which way is more efficient or just better to do the things? Here's my code:

private void methodOne {
    System.out.println("Dummy.class -> methodOne() started");
    ...
    System.out.println("Dummy.class -> methodOne() ended");
}

private void methodTwo {
    System.out.println(logMsg("Dummy", "methodTwo") + "started");
    ...
    System.out.println(logMsg("Dummy", "methodTwo") + "ended");
}

private String logMsg(String className, String methodName) {
    return className + ".class -> " + methodName + "() ";
}

Which one should I use? Is it better to just create whole strings like in methodOne() or just reuse part of them like in methodTwo()?

EDIT: Let's say I want to use logMsg in at least 100 methods

Life44
  • 39
  • 4
  • 6
    Use a dedicated logger, not a `System.out.println`. You can configurate it to always print out the class name and even the method name. – Amongalen Feb 05 '20 at 11:49
  • @Amongalen logging part doesnt matter, I just want to know which method should I use if I really need to do something like that. You've missed the point – Life44 Feb 05 '20 at 11:51
  • (Aside: use a logger.) If you're going to use `logMsg` in 10 places throughout your code, and you might want to alter it some time in the future to do something different, then it's useful. If you're using it in one place, it doesn't look particularly useful, it's just slightly obscuring the meaning of your code. – khelwood Feb 05 '20 at 11:51
  • If you really have to use something like this, the first method is at least better performance-wise - no need to concatenate Strings. – Amongalen Feb 05 '20 at 11:53
  • There is also an option to use an AOP library to create an advice around any method execution to log at the start and at the end. There is obviously a penalty for performance. But you will be writing code at only one place to log what your question requires. – The_Cute_Hedgehog Feb 05 '20 at 11:59
  • Also try using string builder than using concat with '+' – Naveen Kulkarni Feb 05 '20 at 12:15

3 Answers3

0

There are many ways to accomplish this.

1) AspectJ would be a solution if you don't want your code do be cluttered with Logging code.

2) Another idea is to write a dedicated class with a method, that you call at the start and the end of your methods. This class could buffer the messages or write it directly, using a logging framework of your choice.

3) Or you resign using a special class and make calls to the logger directly.

For a first shot I would probably start with option 2, as it will be cleaner than logging directly within each method of your code and having to make calls like if (LOG.isTraceEnabled() {...} every time. AspectJ seems overkill for a first shot.

Jan Held
  • 634
  • 4
  • 14
0

I will omit the obvious answers like "use AOP" or "use a dedicated logger" and will present you an idea for a "homemade" solution.

I think you should consider splitting it into more high-level methods and use StringBuilder to save on memory:

private String getLogMessage(String className, String methodName, String suffix) {
    return (new StringBuilder()).append(className)
                                .append(".class -> ")
                                .append(methodName)
                                .append("() ")
                                .append(suffix)
                                .toString();
}

private void logStart(String className, String methodName) {
    System.out.println(getLogMessage(className, methodName, "started"));
}

private void logEnd(String className, String methodName) {
    System.out.println(getLogMessage(className, methodName, "ended"));
}



private void method() {
    logStart("Dummy", "methodTwo");
    ...
    logEnd("Dummy", "methodTwo");
}
Nikita Karamov
  • 517
  • 1
  • 5
  • 18
0

Well to directly answer your question: the first method is obviously faster.

You have one constant String that will be allocated and reused later. Compiler/JVM will take care of all that.

On the other hand, in the second approach you have:

  1. Method Call
  2. String concatenation inside the method
  3. String concatenation outside the method

Having said that, the most "heavy" part in both cases is a block IO call to System.out.println :)

String concatenation and multiple allocations can also be performance hog when used very frequently (the business method is under high load)

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • Great answer! I'm wondering if I should go for full strings or use the method @Nikita Karamov has mentioned – Life44 Feb 05 '20 at 12:13
  • @Nikita 's suggestion is not relevant for performance considerations (like method 2 but you save one extra concatenation for 'started'/ 'ended' doing it all in string builder) but certainly is better from the code maintainability standpoint. Performance wise: when Java sees multiple concatenations attempts it converts them into string builder. but for small number of concatenations, string builder approach is slower. See https://stackoverflow.com/questions/1532461/stringbuilder-vs-string-concatenation-in-tostring-in-java – Mark Bramnik Feb 05 '20 at 12:19