Does an appropriate algorithm really help improve the quality and ultimately the efficiency of a program?
Can we still produce a good quality program without the algorithm?
Is an appropriate algorithm a MUST in modern programming?
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.
Sign up to join this communityDoes an appropriate algorithm really help improve the quality and ultimately the efficiency of a program?
Can we still produce a good quality program without the algorithm?
Is an appropriate algorithm a MUST in modern programming?
I think this question begs some historical perspective.
Back in the "olden days" (of which I am not a personal witness, so this is only my reconstruction of that era - feel free to correct me if you experienced things differently) HW space and performance was nil compared to today's. So everything people wrote then had to be very efficient. Thus they needed to think a lot about and research to invent the best algorithms to achieve the needed space / time performance to get the job done. Another factor in this was that developers were mostly working on what you may call infrastructure: operating systems, protocol stacks, compilers, device drivers, editors etc. All of this is used a lot by a lot of people, so performance really makes a difference.
Nowadays we are spoilt having incredible HW with multicore processors and Gigabytes of memory in even a basic laptop (heck, even in a mobile phone). Which naturally means that in many cases, performance - thus algorithm - ceased to be the central issue, and it is more important to provide a solution fast than to provide a fast solution. OTOH we have heaps of frameworks helping us solve problems, and encapsulating a large number of algorithms at the same time. So even when we aren't thinking about algorithms, we may very well be using lots of them in the background.
However, there are still areas where performance matters. In these areas you still need to think a lot about your algorithms before writing code. The reason is that the algorithm is the center of the design, determining a lot of data structures and relationships in the surrounding code. And if you find out too late that your algorithm is not scaling well (e.g. it is O(n3) so it looked nice and fast when you tested it on 10 items, but in real life you will have millions), it is very hard, error prone and time consuming to replace it in production code. And micro-optimizations aren't going to help you if the fundamental algorithm is not right for the job.
Just to point out something:
An algorithm is itself a general step-by-step solution of your problem. So, if you solved the problem, you did in fact use an algorithm.
The most important point here is that you must use algorithms to solve problem, one way or the other. Most of the time it's better to think about your problem before you jump to coding - this phase is often called design. But, how much and in which way will you do this depends on you.
Also, you shouldn't mix the concept of algorithm with flowcharts (I suspect this is going on here). Flowcharts are just one graphical representation which can be used and was used in the older days to illustrate an algorithm. It pretty much deprecated nowadays.
EDIT:
There are indeed many ways to represent an algorithm and the programming language code itself is one of them. However, quite often it is much better or easier not to solve entire problem at once but just an outline and then fill the blanks as you go.
My personal favorite here is pseudo code, and only to cover a general abstract outline of the algorithm in question - it's ridiculous to get into details with pseudocode, that's what real code is for.
But real code can be used for the outline. For example, TDD people like to design the algorithm as they code, and since they can't solve it all at once either, they design an outline of the program execution in real code, and use mock objects (or functions, methods...) as blanks to be filled in later.
UML Activity diagrams seem to be a modern incarnation of old-style flowcharts with added notation for the new stuff like polymorphism and multithreading. I can't really say how useful this is, since I didn't really use them much - I'm just mentioning it for completeness.
Also, if you are basing your algorithm on switching between states, then a state diagram is quite helpful.
Generally, any mean you have to simply sketch the idea behind a certain algorithm is a good way to go.
A good analogy is you must know a recipe before you start cooking. Ok you may tweak it as you go, but you still need to know what you want to make before you start. If I want to make a lamb stew I will be doing very different things than if I want to bake a loaf of bread.
Code implements algorithms. Trying to write code without having designed the algorithm is like try to paint a house before the walls are built. Algorithms have been a "MUST" since the beginning of programming.
Being fluent in your language helps to improve quality and productivity. And solving small algorithmic problems is much more useful for that than repeating same MVC stuff 100 times.
Although, I suppose there're other ways to achieve fluency.
Will algorithm become a MUST in modern programming domain?
It's already a 'must', unless you're some 'php ninja' writing 'cool codez'. All the 'best' companies (Google, Amazon, etc) test your algorithmic experience in interview, and I imagine they wouldn't do it for no reason.
But returning to the original point, you should constantly challenge yourself if you want to improve. And since normal jobs (aka "now write CRUD managers for 100 more objects") not always provide a good challenge, algorithms compensate that.
I would say you need at least an initial idea of an algorithm before you started coding. You will likely revise your idea while coding based on data structures etc.
Later you may revise the code again if profiling suggests that there is a performance issue in that area.
The reason is that it is faster to fix mistakes before you have written the mistaken code.
More prosaically, there are routinely measured 10 to 1 productivity differences between different programmers. When you look at the programmers who are at the 10-fold productivity level, they spend the smallest fraction of their time actually coding. Time to type in code should not be the bottleneck. Instead they spend a greater fraction of their time in making sure they have requirements straight, planning, testing, etc.
Conversely when you look at the programmers who dive into coding without a pause, they inevitably have to write the code over and over again as they encounter entirely foreseeable problems, and the final result is less maintainable and more buggy. (Incidentally you did know that an average of 80% of the money spent on software development is in the maintenance phase? Making things maintainable matters. A lot.)
Generally algorithms and data structures first, code later. But it depends a lot upon the programming domain. I used to do a lot of applied math type stuff, and really looked down at the then prevalent waterfall model. That was because the low to medium level algorithms could rarely be taken for granted. Design a large structure around the existance of unwritten subsystems, then discover late in the game that the math for one of those crucial subsystems doesn't work out (is unstable or whatever). So I always thought about the most challenging subsytems first, and if there was any reason for doubt,I wrote and unit tested those first. But, for some problem domains you can just plow ahead without a lot of planning.
Design an algorithm in sections, then split those sections and code each one of them individually. That way you can mix both points of view:
For me, it's pretty much all code. I think that's true for most highly productive programmers. I can write code about as easily as I write text.
As much as possible, I try to capture requirements as executable tests (code). Design is just high-level coding. It's faster and more precise to capture the design in the target language than to capture it in some other form and then translate it.
I have found that most users can't effectively review textual requirements. They do OK with sequential use cases, but the use cases can't capture every aspect of the UI. Best by far is to take a first cut at implementation, let users try it, get their comments, and modify the code accordingly.
When you sit down and start coding, you have an algorithm in mind, whether "designed" or not.
If you sat down and starting coding with no complete algorithm in mind, you'd be doing one of the following:
1) mashing keys randomly. This will probably produce a compiler error
2) writing compilable code that probably does anything except the thing you want it to do
3) writing code to solve little parts of the problem, and building on it as you go in an aggregating fashion, but not really thinking ahead -- so eventually the problem is solved -- but the code is not very efficient manner, and with possibility of having to backtrack and wasting time along the way
So people usually program with an algorithm in their head. It may have be fleshed out or reasoned about on paper or some other medium.
It can be good discipline to think about your attack on a problem away from the keyboard, especially in your earlier days as a programmer. As other answers have noted, as you get more experienced, you can get better at coding some more managable chunks of problem "on the fly". However, for difficult or large problems, thinking and designing away from the keyboard is useful: when engaged with code, you're more likely to be thinking in terms of constructs of the language, and in how to approach the most immediate task in the problem. Whereas thinking about the problem with, say, a pen and paper, frees you more from language aspect of the code and lets you think at a higher more abstract level.
You need to stop looking at software construction as something fundamentally from the construction of anything else of value. It is not. So, like anything else, a well-thought plan or design, however succint, is always needed.
Does an appropriate algorithm really help improve the quality and ultimately the efficiency of a program?
Does an appropriate building plan/schematics help build a quality house efficiently?
Can we still produce a good quality program without the algorithm?
Can you build a good quality house efficiently without an appropriate building plan? As per the Infinite Monkey Theorem, probabilistically, yeah (just as a million monkeys typing at random for eternity will eventually type the complete works of Shakespeare.
Is an appropriate algorithm a MUST in modern programming?
If you don't want to be a code monkey and you want to ensure you don't deliver software that looks and works like shit, yes, it is a must. Every project that I've had to salvage (because the code looked like umaintainable shit) has invariable started with a negative answer to that question.
In fact, modern programming has been the move away from cowboy programming software engineer where planning of some sort if a must.
Even when you have a library of algorithms and data structures at your disposal (.ie. Boost in C++ or the Java collections library), you have to know how that stuff works to use it appropriately, and to compose it into reasonable, higher-level algorithms.
It is not better. It is better not to "design" anything. That is for people who do not write programs. You know, the people with real experience of the problem at hand. If you're a mathematician, engineer or a logistician, fine, you need to work on the process elsewhere. But that is not 'programming'.
Put some kind of test and benchmark in place first.
Then write something, anything. Do refactor-rewrite -loop until you run out of time or can no longer improve.
While many seem to think one can do things with a computer without actually doing anything on a computer, I think this is one of the most common myths out there. Architecture astronautisms.
Also, you can not optimize your algo before it is written.
IOW, "stay close to the metal".