Notice

╠ This is my personal blog and my posts here have nothing to do with my employers or any other association I may have. It is my personal blog for my personal experience, ideas and notes. ╣

Saturday, January 18, 2020

Exception flow control could be expensive.

As a developer sometimes we use exceptions as flow control. It could be expensive. I am going to show you how a simple change could help you to save a lot of time by simply not accepting exception as your code flow controller.
In this example, I will throw an exception if required data is not available during execution I will throw an IllegalArgumentException and in another case, I simply return a value using which call is going to take the decision based on the value then we will see how different it will be.


package com.andy.control;
public class FlowControlExample {
public static void main(String[] args) {
FlowControlExample example = new FlowControlExample();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
try {
String fullName = example.getFullNameThrowException(null, "middle", "");
} catch (IllegalArgumentException e) {
}
}
long timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of exception is thrown. " + (timeTaken / 1000) + " in secs.");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
String fullName = example.getFullNameReturnValue(null, "middle", "");
}
timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of a value returned. " + (timeTaken / 1000) + " in secs.");
}
private String getFullNameThrowException(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
throw new IllegalArgumentException(" First and / or Last name cannot be null or empty.");
}
return firstName + " " + middleName + " " + lastName;
}
private String getFullNameReturnValue(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
return "";
}
return firstName + " " + middleName + " " + lastName;
}
}


Code Output


In case of exception, it will take around a minute for execution and in another case it is insignificant. Both methods are invoked one million times to determine the impact.
Code Output
I request you to think again if you are using exception as your flow controller in a code which will be invoked many times.

Then what if I have to address an exception scenario 

If I need to address an exception scenario then for optimization I could pre-allocate the exception object so that I can use them multiple times.

package com.andy.control;
public class FlowControlExample {
private static final IllegalArgumentException ILLEGAL_ARGUMENT_EXCEPTION = new IllegalArgumentException(" First and / or Last name cannot be null or empty.");
public static void main(String[] args) {
FlowControlExample example = new FlowControlExample();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
try {
String fullName = example.getFullNameThrowException(null, "middle", "");
} catch (IllegalArgumentException e) {
}
}
long timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of exception is thrown. " + timeTaken + " in milliSecs.");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
String fullName = example.getFullNameReturnValue(null, "middle", "");
}
timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of a value returned. " + timeTaken + " in milliSecs.");
}
private String getFullNameThrowException(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
throw ILLEGAL_ARGUMENT_EXCEPTION;
}
return firstName + " " + middleName + " " + lastName;
}
private String getFullNameReturnValue(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
return "";
}
return firstName + " " + middleName + " " + lastName;
}
}

Code Output


In this case, you can see the result is much better but still high than return statement.

Let me know your thoughts about it.