Though the examples are mainly based on searching and sorting and other primitive programming problems, the fundamental concepts and conclusions at the end of each column, are still valuable and hold true as they are 2 decades ago.
The examples and the exercises are challenging and enjoyable. But, don't expect things related to modern programming like related to High Level Programming languages or Databases, this is purely a Basics book focussing on techniques of solving the problems the simplest and the best way.
Some of the gem quotes or conclusions from the book are:
"Coding skill is just one small part of writing correct programs. The majority of the task is problem definition, algorithm design and data structure selection."
"Defining the problem is about ninety percent of the battle"
Characteristics of a good Aircraft(or a good program) - "Simple, few parts, easy to maintain, very strong"
"A designer knows he has arrived perfection not when there is no longer anything to add, but when there is no longer anything to takeaway."
"Good programmers sit back and wait for an insight rather than rushing forward with their first idea"
"A proper view of data does indeed structure programs. Before writing code good programmers thoroughly understand the input, the output and the intermediate data structures around"
I would place this on my list of the top 5 programming books of all time. A must read for every who calls themselves a "programmer".
The reason I did give this book 3 stars was because I can see it being extremely great for uneducated newbies. It will teach them a great deal and have them think about efficiency and general good programming practices.
I was amazed at all of the great reviews I saw with this book. Everyone that gave a review must of been new to computer programming. I was personally expecting a few more advanced topics such as real C and C++ code. Not the .... pseudo code that this author insisted on using.
Overall, this is a great book for neophytes. If you're new to programming, get this book and give it a good once over. Don't pay attention to his style though... As he stated in the book, it's due to the constraints on space and the fact he didn't want to write a 1200 page book. However, if you have gotten to the point where you've studied advanced data structures and algorithms and know what a linked list is and a binary tree and you understand the concepts behind a heap, priority queues and such, I'd go for another book that is going to advance your knowledge, not bring it back a step.
On the other hand, I don't lik that book treats some very specific problem areas, which are unconnecet mutually. Secondly, there are many things in this book which are completely out of date. I don't want to say that they are completely unimportant, but there are things in modern programming that are much more important and in wich you can improve your program much more.
I read this book, as I said before, as collection of funny and interesting stories.
Suppose, for the sake of argument, that you have a binary search that's holding up your loop. Or your Huffman coding just isn't snappy enough? "How is that possible?", you might say, fresh out of computer-science 201, "Didn't we just prove these algorithms are optimal?" Well yes, asymptotically up to an arbitrary constant multiplier. But this is the real world, and your code needs to go faster. If this sounds like your predicament, pull up a chair and read "Programming Pearls"; if it's not, you might wonder what all the fuss is about.
Next, fire up your favorite hardware (Sparc or x86 or PowerPC), favorite language (Perl, Java, or even C), favorite release of that language, along with your favorite interpreter or compiler (Hotspot or standard? GCC or Visual C++). And you'll need a profiler; might as well treat yourself to a good one if you're serious. Then fire up your code with a representative range realistic test data and observe what happens. Function by function, byte by byte. Then try to be as clever as Bentley in (a) figuring out why, (b) trying a range of alternatives, and (c) making it all go faster with minor tuning. Typically, you'll find a single bottleneck taking an order of magnitude more time than everything else, and work on that. Repeat until fast enough.
As well as this simple, yet surprisingly effective and realistic methodology, Bentley provides a range of concrete tips on making things go faster, from tweaking data structures to unfolding loops (especially precomputing low-order cases) to using accumulators and caching, all with an eye to underlying memory, communication and CPU resources.
Real code that has to run fast, like the code that we write at my current company for signal processing, speech recognition and speech synthesis, typically looks like the end-product of Bentley's refactorings. And it gets that way following exactly the path he lays out: analyze the problem, choose the right algorithm (or the right few to evaluate), and then tune it up using profiling.
"Programming Pearls" is the beginning of the road. You will need to look elsewhere for topics such as compression for memory saving, numerical algorithms, effective concurrency and memory sharing, efficient buffered I/O, garbage collection, and the wide range of dynamic programming and heuristic techniques.
For instance, the very first chapter ("Cracking the Oyster") would seem to be about the problem of sorting on disk: surely an archaic concern in these days of 1+GB RAM and 100 GB online media on PCs. But that would entirely miss the point, which Bentley clearly summarizes for us in the "principles" section of this chapter:
* "Defining the problem was 90 percent of this battle..."
* Select an appropriate data structure
* Consider multiple-pass algorithms
* A simple design: "a designer knows he has arrived at perfection not when there is no longer anything to add, but when there is no longer anything to take away." -- St. Exupery
This advice might look like a string of old, worn-out chestnuts as set forth above. But within the context of the specific problem, we can see how the design challenges and solutions follow each other, through several iterations, culminating in a pretty solution, nicely illustrating the principles, and suggesting their relevance to other problems, too.
A thoughtful programmer, no matter whether her domain is machine language or OODBMSes, will come away from any chapter in this book full of new ideas and inspiration.
Problems (good ones) after each section encourage the kind of rumination that is necessary to derive the most from this book. Every few years I take it (and its companion, "More Programming Perals") off the shelf and dip into it again, and always come away enlightened.
o the technical material is well-chosen and well-explained o the writing style is worthy of emulation
Overall, it's worthy of your bookshelf's space.
What Bentley does in each of these columns is take some part of the field of programming--something that every one of us will have run into at some point in our work--and dig underneath it to reveal the part of the problem that is permanent; that doesn't change from language to language. The first two parts cover problem definition, algorithms, data structures, program verification, and efficiency (performance, code tuning, space tuning); the third part applies the lessons to example pseudocode, looking at sorting, searching, heaps, and an example spellchecker.
Bentley writes clearly and enthusiastically, and the columns are a pleasure to read. But the reason so many people love this book is not for the style, it's for the substance--you can't read this book and not come away a better programmer. Inefficiency, clumsiness, inelegance and obscurity will offend you just a little more after you've read it.
It's hard to pick a favourite piece, but here's one nice example from the algorithm design column that shows how little the speed of your Pentium matters if you don't know what you're doing. Bentley presents a particular problem (the details don't matter) and multiple different ways to solve it, calculating the relationship between problem size and run time for each algorithm. He gives, among others, a cubic algorithm (run time equal to a constant, C, times the cube of the problem size, N--i.e. t ~ CN^3), and a linear algorithm with constant K (t ~ KN). He then implemented them both: the former in fine-tuned FORTRAN on a Cray-1 supercomputer; the latter in BASIC on a Radio Shack TRS-80. The constant factors were as different as they could be, but with increasing problem size the TRS-80 eventually has to catch up--and it does. He gives a table showing the results: for a problem size of 1000, the Cray takes three seconds to the TRS-80's 20 seconds; but for a problem size of 1,000,000, the TRS-80 takes five and a half hours, whereas the Cray would take 95 years.
The book is informative, entertaining, and will painlessly make you a better programmer. What more can you ask?