• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Long vs. short methods

 
Ranch Hand
Posts: 57
3
Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In another post, Campbell Ritchie made this statement:

Campbell Ritchie wrote:You should not combine two methods into one. You should normally divide large methods into several smaller methods.


I read a few articles on why shorter methods are better (like this one), but doesn't it take more processing power to make multiple method calls as opposed to having logic bumped into longer, more verbose methods?
 
Marshal
Posts: 73968
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For the few nanoseconds it might save, you may have hours of work if you need to update the class.

I haven't got the time for a fuller answer now, but maybe somebody else will be able to help.
 
author
Posts: 23907
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:For the few nanoseconds it might save, you may have hours of work if you need to update the class.



Considering that most of today's processors can do a jump to subroutine in one cycle, and on a 3 ghz machine, one cycle is about 300 pico-seconds (I think), we are talking about a ridiculously small amount of time here.

Heck, we can't even use the tight loop argument (meaning what if we call the method millions of times), as for that argument to work, the method has to do almost nothing.

Henry
 
Ranch Hand
Posts: 58
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The primary reason to use methods is to reduce complexity and, concomitantly, cognitive overload. By failing to create nice, short, cohesive methods, you're increasing the complexity of your program, which is a far, far greater sin than any (minuscule) overhead that might result from multiple method calls. Just as classes represent meaningful abstractions, so do methods. (With methods we're abstracting over procedures rather than entities.) You want your methods to be as simple as possible, (though obviously you can take this to extremes and create far too many methods on a given class, through over-decomposition).

The short answer, though, is: don't give the slightest consideration to any perceived overhead of calling multiple methods.
 
Marshal
Posts: 16590
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Approach it like you would with a relational database design. You strive for Third Normal Form in your database designs and only when you find good opportunities to improve performance do you go and denormalize certain parts of it. Factoring of code is the same way. You strive for well-factored code first, then perhaps when you find a good opportunity to improve performance, you can in-line code that's in a separate method. Compilers these days are pretty good at automatically finding optimizations and they generally keep improving with every new version. Processors are also doubling in power at regular intervals. Programmers, on the other hand, will always be hindered by poorly factored code. As Campbell and the article you cited suggest, focus on making your code testable, maintainable, and extensible first by making it clean and well-factored. This gives you the most bang for your development buck.

Remember what Donald Knuth said: "Premature optimization is the root of all evil."

Lastly, programmers have a horrible track record at optimizing by intuition. Experienced programmers know to use a profiler to find the bottlenecks in their code.
 
Gordon Brown
Ranch Hand
Posts: 58
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Incidentally, I'm just reading Chapter 7 of Steve McConnell's Code Complete, 2nd Edition. It has excellent advice on design considerations with respect to routines. 7.4 is "How long can a routine be?"
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you write code, you should never try to write it in a "clever" way because you think that your clever tricks will make the program "more efficient". The fact is that you don't know if clever tricks really help or not (and in fact, often they don't help at all or they even make the program perform worse), but using such tricks will make your program much harder to maintain - for people who will need to work with your code later, or even for yourself in the future.

The computer science professor Donald Knuth ows part of his fame to his statement:

Donald Knuth wrote:
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.


So, when you design and write code, first and foremost design it with a logical and clear structure, and write it so that it easy to read and understand for humans.

Don't optimize code based on vague feelings, because you have some vague idea that some clever trick is "more efficient" than the straightforward thing to do. Your vague feeling is most likely wrong. Compilers are very good at optimizing code and clever tricks can confuse the compiler, leading to executable code that is less optimal.

Only optimize code if there is really a performance problem. And if you do need to optimize, then take the scientific approach - don't guess, but measure with a profiler where the actual performance problem is, and focus on improving the bottleneck in your code.

Most often, the biggest gains are made by choosing better algorithms and not by micro-optimizing statements.

Putting a lot of code in one method just because you have the vague feeling that method calls are "expensive" is a typical example of a premature micro-optimization which will most likely not matter anything at all for the performance of the program, but it will make your code a lot harder to understand and maintain.

Note that Java's JIT compiler is very good in optimizing things; one of the most important optimizations it does is inlining methods. For example, getter methods cost almost nothing in Java, because those are almost always inlined - which means at runtime it's just as if you're reading the member variable directly, without any method call overhead.
 
Bartender
Posts: 689
17
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In the words of Donald Knuth, "premature optimization is the root of all evil".

As others have said, the amount of time a method call takes is likely to be tiny and will probably be dwarfed by other inefficiencies. But on top of that we can't know what optimisations the compiler and JVM will make.

I'd definitely value maintainability until an actual performance problem is identified.
 
Tim Harris
Ranch Hand
Posts: 57
3
Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:When you write code, you should never try to write it in a "clever" way because you think that your clever tricks will make the program "more efficient". The fact is that you don't know if clever tricks really help or not...



This right here is pretty much the reason why I don't bother with trying for the most part - there's not a real efficient way for me to make a test case of "hey, how much time am I shaving off if I do xyz as opposed to abc"? I've seen things like System.currentTimeMillis() and using the manager package, but they don't seem very accurate.

I suppose the point is that calling a method in of itself is not that resource intensive, so chained method calls really don't add up that much?
 
Sheriff
Posts: 67590
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike. J. Thompson wrote:In the words of Donald Knuth, "premature optimization is the root of all evil".


Should be tattooed on the backs of developers' hands so that they have to look at it all the time.

Strike "wouldn't it be faster to ..." from your vocabulary¹.








¹ Unless and until there's a demonstrable performance issue that needs to be addressed.
 
Junilu Lacar
Marshal
Posts: 16590
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Harris wrote:I suppose the point is that calling a method in of itself is not that resource intensive, so chained method calls really don't add up that much?


This is another case where I would not worry too much about optimization/performance more than I would about the cognitive weight of the chained calls. Chained method calls can make for very fluent APIs. On the other hand, they can also lead to very confusing and difficult-to-debug code if not designed well.
 
Bear Bibeault
Sheriff
Posts: 67590
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You want your needle to be heavily in the green.

 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Harris wrote:I've seen things like System.currentTimeMillis() and using the manager package, but they don't seem very accurate.


Doing micro-benchmarks in Java is hard. First of all, the resolution of the clock that System.currentTimeMillis() uses is not very good on most operating systems, so you can't use it for accurately timing very short intervals of time. But more importantly, Java's JIT compiler which compiles Java bytecode to machine language at runtime and which does a lot of optimizations, and Java's garbage collector make it very hard to measure exactly what code is doing.

If you really want to do micro-benchmarks, you should use a tool such as JMH (Java Microbenchmarking Harness) which is built by Oracle's JDK engineers themselves.
 
Sheriff
Posts: 8064
569
Mac OS X VI Editor BSD Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When saw Bear's uploaded image, instantly remembered phrase below..

C.A.R. Hoare wrote:“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

 
Ranch Hand
Posts: 789
Python C++ Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Harris wrote:I read a few articles on why shorter methods are better (like this one), but doesn't it take more processing power to make multiple method calls as opposed to having logic bumped into longer, more verbose methods?



That is a good little article. Here's an important thing you need to know -- regarding programming concern about power and speed, everything except the algorithm complexity is usually ignored. In other words if you make a change to a constant time algorithm and it stays constant time, then no problem. But if you change the code such that the constant time algorithm becomes linear time, say, only then is it a significant change. So in regard to speed and power, just be concerned with algorithmic time complexity. An obvious exception would be when you're working on a little low power controller running off a solar cell, say, and you need to make best use of every microamp.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:¹ Unless and until there's a demonstrable performance issue that needs to be addressed.



There's one exception where I would say you should make your decision based on performance. If you are faced with a choice and all options are equal other than performance, then make the choice you think will be most performant. For example if you're using a List and you need to decide whether to use an ArrayList, a LinkedList or some other implementation then pick the one that is most performant under your expected use case. You may of course be wrong and have to come back and change implementation, but that's why we program to Interfaces ;)

It may also be the case that your use of the List is not even a bottleneck and it wouldn't have made any significant difference which implementation you picked, but you still needed to pick an implementation.
 
Campbell Ritchie
Marshal
Posts: 73968
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This question has proved to be very interesting and has raised lots of interesting responses

People have been on about optimisations, e.g. the JIT runtime. You may not have grasped the scope of optimisations available. 99% of the time the compiler and runtime can do a far better job of optimising performance than you can, but you need to help it. The way to do that as you will see in this interview, is …

In that interview, Brian Goetz wrote:Write dumb code.

If you scroll down, you find soebody else's opinion of “dumb code” (in the same link).
“Dumb” does not mean stupid, but straightforward. If you write simple straightforward code the optimisers in the compiler and the runtime will be better able to optimise things and produce great improvements in performance. 99% of the time better than you can by trying to write clever code. With the exception, as Guillermo Ishi point out, of using inefficient algorithms. If you use bubble sort you will find your sorting much slower than if you use merge sort or quick sort. And the only thing that can improve that is changing to a faster algorithm
 
Campbell Ritchie
Marshal
Posts: 73968
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

A few minutes ago, I wrote:. . . If you use bubble sort you will find your sorting much slower than if you use merge sort or quick sort. . . .

And I spelt it wrongly, which I shall correct.

Actually that is not quite true; if you try merge sort on a 10‑element array it will probably take longer than bubble sort because bubble sort uses simpler code and it takes less time for each pass through the array.
 
Tim Harris
Ranch Hand
Posts: 57
3
Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There's been lots of good feedback in this thread, and I thank everyone for their input - special thanks to Jesper for informing me of JMH, which I'd like to use to further use to explore the issue in my own time (and probably prove everyone here right.)
 
Campbell Ritchie
Marshal
Posts: 73968
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome
 
Campbell Ritchie
Marshal
Posts: 73968
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:. . .
Strike "wouldn't it be faster to ..." from your vocabulary
. . .

Even when followed by, “shoot all of ***,” or similar?
 
Tim Harris
Ranch Hand
Posts: 57
3
Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Bear Bibeault wrote:. . .
Strike "wouldn't it be faster to ..." from your vocabulary
. . .

Even when followed by, “shoot all of ***,” or similar?



Shooting isn't faster, just removes the problem of those pesky end users. ;)
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Harris wrote:There's been lots of good feedback in this thread, and I thank everyone for their input - special thanks to Jesper for informing me of JMH, which I'd like to use to further use to explore the issue in my own time (and probably prove everyone here right.)


It's probably a bit late to add my two-penn'orth, but I'm going to play the Devil's advocate here:

In addition to Mike's "exception", I'd add one other - that it is reasonable to optimize when a platform clearly fails to itself.

Those of you with longer memories than me will probably remember the days when synchronization in Java was a dog - such a dog that it spawned all sorts of idioms (good and bad; mostly the latter) to avoid it - pretty much all of which have been simply castigated as "premature optimization".
But what's a poor Java programmer to do? If your program simply won't run quickly enough, and you have a magic bullet that provably speeds it up, I say: use it, whether it's PO or not.

The problem with stuff like that is not the doing of it, it's:
a. Understanding that you are optimizing, and being able to justify it.
b. Remembering where you did it.
c. (probably most important) Planning for refactoring if a time ever comes when it's not needed.

I should add that I'm a great believer in POITROAE, but there are occasions - albeit extremely rare - when it's unavoidable.

Winston
 
lowercase baba
Posts: 13002
66
Chrome Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote: If your program simply won't run quickly enough, and you have a magic bullet that provably speeds it up, I say: use it, whether it's PO or not.

The problem with stuff like that is not the doing of it, it's:
a. Understanding that you are optimizing, and being able to justify it.
b. Remembering where you did it.
c. (probably most important) Planning for refactoring if a time ever comes when it's not needed.

I should add that I'm a great believer in POITROAE, but there are occasions - albeit extremely rare - when it's unavoidable.


I would argue that what you have above is most assuredly NOT premature optimization. "understanding what you are optimizing" implies you have analyzed, measured, and understood what you did. if "[Y]our program simply won't run quickly enough", then you have clearly measured how fast it runs and have some metric defined of what "fast enough" is.

PO in my mind is "i want my program to run as fast as possible so i'll try THIS because i just KNOW it will speed things up". What you describe is (at least in my mine) simply "optimization".
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

fred rosenberger wrote:PO in my mind is "i want my program to run as fast as possible so i'll try THIS because i just KNOW it will speed things up". What you describe is (at least in my mine) simply "optimization".


You're probably right, but most of the idioms I referred to were made redundant (and in some cases invalid) by later enhancements to the memory model, causing many commentators to dismiss them as PO because they exhibited many of the same symptoms.

I guess it just highlights the fact that whenever you optimize, you need to keep checking to make sure that your "extraware" continues to provide benefit.

Winston
 
Saloon Keeper
Posts: 24283
167
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One reason why you should not "code efficiently" these days is because a LOT of optimizations are done automatically. For example, if there are 3 or 4 methods all called from a parent method and the compiler determines that it's profitable and safe to do so, the compiler may automatically "inline" all the code into a single method. So, in other words, you can have the significant benefits of well-laid out code and still not have the extra overhead of having them set up and destroy separate function environments. You may also spare the compiler some resources, since the amount of code that it has to do fine-grained processing on within a method would be less, since there's less code in the smaller method.

Note that this is different than choosing smart algorithms. Statistics indicated that rarely could you get more than a 5-10% speedup by doing machine-language level tricks, but the choice of an algorithm can be critical.

Here's my favorite example, from a critical system app that I once tuned up. The app maintained a list of items in the sequence A, B, C, X, D . ,,, M, N, ...W, Y, Z. There was, incidentally, a VERY good reason why X was in the middle.

If you look at the 4 most popular sort algorithms: bubble, shell, quick, and heap, you can see that almost all of them find this to be a bad starting point. For a bubble sort, that "X" has to percolate up inch by inch until it's in the proper place. For heap and quick sorts, the sorting heaps end up horribly lopsided so many passes are required to get things balanced and sorted. The Shell-Metzner sort, however, was ideal. Shellsort is basically a bubble except that instead of comparing and swapping adjacent elements, you use a binary divide-and-conquer compare/swap approach.

This particular system ran upwards of 100 times a day and processed virtually every scrap of output that the mainframe ran in production, so it was well worth the effort to choose a good algorithm.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic