Programming Pearls by Jon Bentley

Programming Pearls

5.6/104 min read

8/1/17

  • Careful analysis of a small problem can sometimes yield tremendous practical benefits

  • Focus on the right problem: defining the problem is 90% of the battle

  • Bitmap data structure: this data structure represents a dense set over a finite domain when element occurs at most once and no other data is associated with the element

  • A time-space tradeoff: by using more time, a program can run in less space, tradeoffs are common to all engineering disciplines

  • 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

  • Simple programs are more reliable, secure, robust, efficient and are easier to build and maintain

  • A problem that seems difficult may have a simple, unexpected solution

  • Problem definition: determining what the user really wants to do is an essential part of programming

  • What primitives will we use to solve the problem?

  • What new basic operation will make the problem trivial?

  • A problem solver's perspective: be a bit lazy. Sit back and wait for an insight before rushing forward with your first idea

  • Judgment comes only with the experience of solving problems and reflecting on their solutions

  • You can make programs smaller and better by restructuring their initial data

  • The programmer at wits end for lack of space can often do best by disentangling himself for his code, rearing back, and contemplating his data

  • Encapsulate complex structures

  • When you read a sophisticated data structure, define it in abstract terms, and express those operations in a class

  • Let the data structure the program

  • Before writing code, good programmers thoroughly understand the input, the output and the intermediate data structures around which their programs are built

  • Correctness has 3 parts: initalization, preservation, termination

  • Assertions allow a programmer to enunciate the relations between input, program variables, and output, which describe the 'state' of a program, precisely

  • Functions: programs by contract. Precondition: the state that must be true before it is called. Postcondition: what is guaranteed on termination

  • Verify code correctness by executing the program by hand on one input

  • Understand the code at all times and resist those foul urges to 'just change it until it works'

  • Assertions are crucial for maintaining a program and can give invaluable insight about the program state

  • Keeping the code simple is usually the key to correctness

  • An assert is used to state a belief about an expression and will raise an error if it is not true

  • Correct code: walkthrough manually with input and check for output, use assertions throughout the code, use automated testing, check runtime with simple experiments

  • Coding: sketch a hard function in a convenient high-level pseudocode, then translate it into the implementation language

  • There has to be a logical explanation, no matter how mysterious the system's behavior may seem

  • Programmer's ultimate goal: a simple, powerful program that delights its users and does not vex its builders

  • Performance improvements: algorithms and data structures, algorithm tuning, data structure reorganization, code tuning, hardware

  • Decompose a large system into modules

  • The importance of simple design can't be overemphasized

  • Dynamic programming: save state to avoid recomputation

  • Preprocess information into data structures

  • Use divide-and-conquer algorithms

  • Cumulatives: use cumulative tables

  • Code tuning: locating expensive parts of an existing program and make little changes to improve its speed

  • Caching: data accessed most often should be the cheapest to access

  • Premature optimization is the root of much programming evil

  • Less data to manipulate usually means less time to manipulate it

  • Don't store, recompute

  • Store, don't retransmit over the network

  • Dynamic allocation: only allocating space when it is needed

  • Problem-solving: 1. understand the perceived problem 2. specify an abstract problem 3. explore the design space 4. implement one solution 5. retrospect

  • The purpose of software engineering is to control complexity, not create it

  • Design problem suggestions: 1. work on the right problem 2. look at the data 3. design with components 4. strive for elegance