I’m too often facing situations where I need to get several types of information from a method. I usually think long and hard to circumvent these situations but I’m thinking it’s pointless work that I’m doing. My question: should I prefer to take a slight performance hit in these situations, like iterating over an array twice for example (resulting in slower but cleaner code) or try to return everything at once with an instance of a custom helper class?
Here’s a case example for the sake of it
char[] arr = {'a', 'b', 'a', 'c', 'a'};
int count = 0; // 'a' and 'b' count
String word= ""; // 'a's and 'b's glued together in their occurring order
for (int i = 0; i < arr.length; ++i) {
for (int j = 0; j <= arr[0].length; ++j) {
if (arr[i][j] == 'a' || arr[i][j] == 'b') {
++count;
word += Character.toString(arr[i][j]);
}
}
}
// return both 'count' and 'word' inside a new object or iterate twice?
13
Premature Optimization is the root of all evil.
As Donald Knuth said,
Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.
Regardless of language, write your code to be as clear as you can. If looping twice really results in clearer code, go ahead and write that. A descent compiler may refactor away the second loop, or the overhead may be bottlenecked by other areas of your program. Unless your software is very widely used, it’s likely that the time your successor spends trying to decipher a quick but complicated block of code will be more expensive than the fractionally increased runtime.
If, after testing, you find that a given program is running unacceptably slow, a refactor to the more complex means may be appropriate. But these situations are often difficult to identify in advance, because of this uncertainty more than anything else, you should err on the side of clarity over “performance” whenever such are in contention.
7
The “premature optimisation is the root of all evil” thingy is nice and cute, but it is often misinterpreted and should not be used as an excuse to write poor code: if you can easily write code that obviously performs better, you should (for example by choosing the right data structure or avoiding to loop twice when one loop can do the job).
In the simple example you showed, you could create a class that handles the specific job. Something like:
class FindAGoodName {
FindAGoodName(char[] array, char... retain letters) {
//your loop here
}
int getCount() {}
String getWord() {}
}
The code will be as readable (possibly more readable) and you only loop once. Everybody happy.
4
If the code change results in a…
- measurable performance improvement that
- satisfies a non-functional software requirement, and
- you cannot satisfy the requirement using simpler code
…then make the code change. Otherwise, you’re almost always better off writing code that is easier to understand and more maintainable.
3