Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] Premature Optimization is the Root of All Evil

#1
Premature Optimization is the Root of All Evil

This chapter draft is part of my upcoming book “From One to Zero” (NoStarch 2021). You’ll learn about the concept of premature optimization and why it hurts your programming productivity. Premature optimization is one of the main problems of poorly written code. But what is it anyway?

Definition Premature Optimization


Definition: Premature optimization is the act of spending valuable resources—such as time, effort, lines of code, or even simplicity—on unnecessary code optimizations.

There’s nothing wrong with optimized code.

The problem is that there’s no such thing as free lunch. If you think you optimize code snippets, what you’re really doing is to trade one variable (e.g., complexity) against another variable (e.g., performance).

Sometimes you can obtain clean code that is also more performant and easier to read—but you must spend time to get to this state! Other times, you prematurely spend more lines of code on a state-of-the-art algorithm to improve execution speed. For example, you may add 30% more lines of code to improve execution speed by 0.1%. These types of trade-offs will screw up your whole software development process when done repeatedly.

Donald Knuth Quote Premature Optimization


But don’t take my word for it. Here’s what one of the most famous computer scientists of all times, Donald Knuth, says about premature optimization:

“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.”Donald Knuth

Knuth argues that most of the time, you shouldn’t bother tweaking your code to obtain small efficiency gains. Let’s dive into five practical instances of premature optimization to see how it can get you.

Six Examples of Premature Optimization


There are many situations where premature optimization may occur. Watch out for those! Next, I’ll show you six instances—but I’m sure there are more.

Premature Optimization of Code Functions


Free stock photo of close-up, code, coder

First, you spend a lot of time optimizing a code function or code snippet that you just cannot stand leaving unoptimized. You argue that it’s a bad programming style to use the naïve method, and you should use more efficient data structures or algorithms to tackle the problem. So, you dive into learning mode, and you find better and better algorithms. Finally, you decide on one that’s considered best—but it takes you hours and hours to make them work. The optimization was premature because, as it turns out, your code snippet is executed only seldom, and it doesn’t result in meaningful performance improvements.

Premature Optimization of Software Product’s Features


Engineers Testing Product

Second, you add more features to your software product because you believe that users will need them. You optimize for expected but unproven user needs. Say you develop a smartphone app that translates text into morse code lights. Instead of developing the minimum viable product (MVP, see Chapter 3) that does just that, you add more and more features that you expect are necessary, such as a text to audio conversion and even a receiver that translates light signals to text. Later you find out that your users never use these features. Premature optimization has significantly slowed down your product development cycle and reduced your learning speed.

Premature Optimization of Planning Phase


Planning Phase

Third, you prematurely optimize your planning phase, trying to find solutions to all kinds of problems that may occur. While it’s very costly to avoid planning, many people never stop planning, which can be just as costly! Only now the costs are opportunity costs of not taking action. Making a software product a reality requires you to ship something of value to the real world—even if this thing is not perfect, yet. You need user feedback and a reality check before even knowing which problems will hit you the hardest. Planning can help you avoid many pitfalls, but if you’re the type of person without a bias towards action, all your planning will turn into nothing of value.

Premature Optimization of Scalability


Distributed System

Fourth, you prematurely optimize the scalability of your application. Expecting millions of visitors, you design a distributed architecture that dynamically adds virtual machines to handle peak load if necessary. Distributed systems are complex and error-prone, and it takes you months to make your system work. Even worse, I’ve seen more cases where the distribution has reduced an application’s scalability due to an increased overhead for communication and data consistency. Scalable distributed systems always come at a price—are you sure you need to pay it? What’s the point of being able to scale to millions of users if you haven’t even served your first one?

Premature Optimization of Test Design


Test

Fifth, you believe in test-driven development, and you insist on 100% test coverage. Some functions don’t lend themselves to unit tests because of their non-deterministic input (e.g., functions that process free text from users). Even though it has little value, you prematurely optimize for a perfect coverage of unit tests, and it slows down the software development cycle while introducing unnecessary complexity into the project.

Premature Optimization of Object-Orientated World Building


World Building

Sixth, you believe in object orientation and insist on modeling the world using a complex hierarchy of classes. For example, you write a small computer game about car racing. You create a class hierarchy where the Porsche class inherits from the Car class, which inherits from the Vehicle class. In many cases, these types of stacked inheritance structures add unnecessary complexity and could be avoided. You’ve prematurely optimized your code to model a world with more details than the application needs.

Code Example of Premature Optimization Gone Bad


Let’s consider a small Python application that should serve as an example for a case where premature optimization went bad. Say, three colleagues Alice, Bob, and Carl regularly play poker games in the evenings. They need to keep track during a game night who owes whom. As Alice is a passionate programmer, she decides to create a small application that tracks the balances of a number of players.

She comes up with the code that serves the purpose well.

transactions = []
balances = {} def transfer(sender, receiver, amount): transactions.append((sender, receiver, amount)) if not sender in balances: balances[sender] = 0 if not receiver in balances: balances[receiver] = 0 balances[sender] -= amount balances[receiver] += amount def get_balance(user): return balances[user] def max_transaction(): return max(transactions, key=lambda x:x[2]) transfer('Alice', 'Bob', 2000)
transfer('Bob', 'Carl', 4000)
transfer('Alice', 'Carl', 2000) print('Balance Alice: ' + str(get_balance('Alice')))
print('Balance Bob: ' + str(get_balance('Bob')))
print('Balance Carl: ' + str(get_balance('Carl'))) print('Max Transaction: ' + str(max_transaction())) transfer('Alice', 'Bob', 1000)
transfer('Carl', 'Alice', 8000) print('Balance Alice: ' + str(get_balance('Alice')))
print('Balance Bob: ' + str(get_balance('Bob')))
print('Balance Carl: ' + str(get_balance('Carl'))) print('Max Transaction: ' + str(max_transaction()))

Listing: Simple script to track transactions and balances.

The script has two global variables transactions and balances. The list transactions tracks the transactions as they occurred during a game night. Each transaction is a tuple of sender identifier, receiver identifier, and the amount to be transferred from the sender to the receiver. The dictionary balances tracks the mapping from user identifier to the number of credits based on the occurred transactions.

The function transfer(sender, receiver, amount) creates and stores a new transaction in the global list, creates new balances for users sender and receiver if they haven’t already been created, and updates the balances according to the transaction. The function get_balance(user) returns the balance of the user given as an argument. The function max_transaction() goes over all transactions and returns the one that has the maximum value in the third tuple element—the transaction amount.

The application works—it returns the following output:

Balance Alice: -4000
Balance Bob: -2000
Balance Carl: 6000
Max Transaction: ('Bob', 'Carl', 4000)
Balance Alice: 3000
Balance Bob: -1000
Balance Carl: -2000
Max Transaction: ('Carl', 'Alice', 8000)

But Alice isn’t happy with the application. She realizes that calling max_transaction() results in some inefficiencies due to redundant calculations—the script goes over the list transactions twice to find the transaction with the maximum amount. The second time, it could theoretically reuse the result of the first call and only look at the new transactions.

To make the code more efficient, she adds another global variable max_transaction that keeps track of the maximum transaction amount ever seen.

transactions = []
balances = {}
max_transaction = ('X', 'Y', -9999999) def transfer(sender, receiver, amount):
… if amount > max_transaction[2]: max_transaction = (sender, receiver, amount)

By adding more complexity to the code, it is now more performant—but at what costs? The added complexity results in no meaningful performance benefit for the small applications for which Alice is using the code. It makes it more complicated and reduces maintainability. Nobody will ever recognize the performance benefit in the evening gaming sessions. But Alice’s progress will slow down as she adds more and more global variables (e.g., tracking the minimal transaction amounts etc.). The optimization clearly was a premature optimization without need for the concrete application.


Do you want to develop the skills of a well-rounded Python professional—while getting paid in the process? Become a Python freelancer and order your book Leaving the Rat Race with Python on Amazon (Kindle/Print)!

Leaving the Rat Race with Python Book

Where to Go From Here?


Enough theory, let’s get some practice!

To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?

Practice projects is how you sharpen your saw in coding!

Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?

Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.

Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.

Join the free webinar now!

The post Premature Optimization is the Root of All Evil first appeared on Finxter.



https://www.sickgaming.net/blog/2020/12/...-all-evil/
Reply



Forum Jump:

[-]
Active Threads
(Indie Deal) FREE Disgraced, Waifu Desir...
Last Post: xSicKxBot
Today 07:52 PM
» Replies: 0
» Views: 2
Unreal Engine May 2021 Free Marketplace ...
Last Post: xSicKxBot
Today 07:52 PM
» Replies: 0
» Views: 3
Microsoft - Humans and AI: Meet Juan Lav...
Last Post: xSicKxBot
Today 07:51 PM
» Replies: 0
» Views: 2
Fedora - Introducing the Fedora i3 Spin
Last Post: xSicKxBot
Today 07:51 PM
» Replies: 0
» Views: 2
News - Detective Pikachu Star Doesn’t Se...
Last Post: xSicKxBot
Today 07:51 PM
» Replies: 0
» Views: 2
News - NPD Reveals Top 10 Best-Selling S...
Last Post: xSicKxBot
Today 07:51 PM
» Replies: 0
» Views: 2
News - Blizzard Loses Millions Of Monthl...
Last Post: xSicKxBot
Today 07:50 PM
» Replies: 0
» Views: 8
AppleInsider - Apple Pay launches in Isr...
Last Post: xSicKxBot
Today 12:18 PM
» Replies: 0
» Views: 10
Microsoft - Teachers: Thank you for insp...
Last Post: xSicKxBot
Today 12:18 PM
» Replies: 0
» Views: 6
News - UK Charts: New Pokémon Snap Tops ...
Last Post: xSicKxBot
Today 12:17 PM
» Replies: 0
» Views: 7

[-]
Twitter

Copyright © SickGaming.net 2012-2020