-3

I am currently working on a project which is quite critical to performance. And as I am not that familiar with cpu workloads and stuff I wanted to know what is better (faster):

Foo doSomething1() { 
    try {
        return getVal();
    } finally {
        doSomeCleanup();
    }
}

or

Foo doSomething2() { 
    final Foo result = getVal();
    doSomeCleanup();
    return result;
}
Pwnstar
  • 2,333
  • 2
  • 29
  • 52
  • 1
    Does this answer your question? [Why do we use finally blocks?](https://stackoverflow.com/questions/3421486/why-do-we-use-finally-blocks) – Joe Apr 27 '20 at 08:08
  • This code seems rather brittle: it's apparently possible to call `getVal()` without doing the cleanup. It would be better to avoid doing things that need cleaning up; but if you do, those things should be managed more robustly (e.g. do the cleanup in `getVal()`; or set up the resources in the method calling getVal, then call, then clean up). – Andy Turner Apr 27 '20 at 08:10
  • Actually this is a simple example of the whole thing. I just wanted to know what is faster, not how to use try-finally appropriate. I am writing an iterator which combines 4 nested loops to one. These methods have more than just 3 lines of code. – Pwnstar Apr 27 '20 at 08:45

2 Answers2

1

Normally the result is expected for further processing and therefore it is in my opinion more critical to work with it BEFORE the cleanup starts. From the performance point of view the Cleanup action is usually uncritical and could be done "later". In short: the version with finally cleanup is faster than the chunk with cleanup

  • I can confirm that. I seems like not saving a variable slightly performs better. – Pwnstar Apr 27 '20 at 08:46
  • @Spektakulatius Really? Having one more or less variable is only slightly more relevant than having one more empty line in the source code. The performance may differ, but that's essentially random (and measuring the performance correctly is pretty hard; see JMH). – maaartinus Apr 28 '20 at 05:01
  • 1
    @maaartinus It depends on the cleaning task. The try-finally execution takes more time than other simple statement such as an if. The performance issue is the case of a profound analysis. As I said, if the cleaning task is simple clear() of an ArrayList then the "chunk" is better and faster than the try-finally. –  Apr 28 '20 at 10:41
  • Actually I rethought my question and know I happen to see how dumb I was :D I actually always would prefer the finally approach even though milliseconds are a difference, because in an error case the cleanup is executed anytime which can make the difference :D – Pwnstar Aug 28 '20 at 08:48
0

Unless you expect method getVal() to be able to throw an exception try-finally is misused. The second option is the correct one. However, if you want to be able to perform your clean-up for both cases when getVal() may or may not throw an exception than try-finally is appropriate.

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • Right: the code does different things. That's what determines which to choose: performance is worth nothing if it does the wrong thing. – Andy Turner Apr 27 '20 at 08:06
  • No. I don't care if there is an exception thrown. If there would be an exception it should break the whole execution anyway. – Pwnstar Apr 27 '20 at 08:42
  • @Spektakulatius - then definitely DO NOT use try-finally. Use your second option – Michael Gantman Apr 27 '20 at 08:52
  • Nope I use the one which is faster. Not the one which is prettier – Pwnstar Apr 27 '20 at 09:29
  • Exception handling is VERY expensive performance-vise, so here you will be by far better off using your second option. Also in your first option, you will not get return value before the clean-up. Clean-up will be performed before return. – Michael Gantman Apr 27 '20 at 09:38
  • How often do I need to repeat myself. I don't care if an exception is thrown. That means that I don't care if it would take long if an exception is handled: I am just focused on speed when there is no exception. Can you proove that try-finally is outperformed by the other example? In my tests the try-finally is about 5ms faster than the other. – Pwnstar Apr 27 '20 at 10:07
  • Well, if you use try-finally it is called an exception handling, regardless of whether an exception is thrown or not. try-finally comes with a performance cost. In my opinion, it is hands down absolutely wrong to use it here in your case. Your second option should be working faster. I don't know why it is not in your case. In my position, I am responsible for code review of others among other things. I would not let try-finally to be used in this case. This is my opinion. Of course, you are free to take it or leave it. – Michael Gantman Apr 27 '20 at 10:33
  • In my test with the profiler the "finally" example works faster than the other. – Pwnstar Apr 27 '20 at 11:10
  • Finally is free (or nearly free), when there's no actual exception. It's just an entry in a table to be used by the exception handler, when it gets called. What's expensive is throwing an exception. `+++` There's no measurable speed difference to be expected here. IMHO try-finally is fine, when the cleanup is important (the OP says that then the program terminates anyway, but thing can change). – maaartinus Apr 28 '20 at 05:08
  • Agreed with maaartinus about the issue of exception handling. Spektakulatius goes on an unconventional way with the try-finally. His purpose (so I've guessed) is to process the necessary and FINALLY the unnecessary when everything is done orderly. –  Apr 28 '20 at 10:51