Good code criteria

Good code is understandable and not greedy. Let's talk about it.

Time to understanding

The main criterion for good code is the time T it takes for a non-author to understand the code. Not "I kind of get it", but a deep enough understanding to make changes without breaking anything.

The lower the T, the better the code.

Let's say Alice and Bob implemented the same feature, and you want to change the code behind it. If you understand Alice's code in 10 minutes, and Bob's code in 30 minutes — Alice's code is better. It doesn't matter how layered Bob's architecture is, whether he used a functional approach, a modern framework, etc.

The T-metric is different for a beginner and an experienced programmer. So it makes sense to focus on the average level of developers who will be working with the code.

If you have a team of people working for 10+ years, and everyone writes compilers in their spare time — even very complex code will have a low T. If you have a huge turnover and hire yesterday's students — the code should be rather primitive, so that T does not shoot through the roof.

It's not easy to measure T directly, so teams typically focus on practices that affect T, such as:

  • enforcing code style,
  • checking for code smells,
  • reducing cyclomatic complexity,
  • maintaining acyclic module dependencies,
  • code review.

Resource usage

The second criterion for good code is the amount of resources R it consumes (time, CPU, memory, disk). The smaller the R, the better the code.

Let's say Alice and Bob implemented a feature with the same T. If Alice's code time complexity is O(n) and Bob's is O(n²) (with the same consumption of other resources) — Alice's code is better (assuming real-world n is sufficiently large).

What about the infamous "sacrifice readability for efficiency"? For each problem, there is a resource consumption threshold R₀ that the solution should not exceed. If R < R₀, there is no point in degrading T to further reduce R.

If a non-critical service processes a request in 50ms, you don't need to rewrite it from Python to C to reduce the time to 5ms. It is already fast enough.

If the code has a high T and a low R, in most cases you can reduce T (refactor the code for better understanding) while keeping R < R₀ (keeping resource usage reasonably low).

Sometimes, when resources are limited or the input data is huge, it may not be possible to achieve R < R₀ (e.g., making a task run in less than 5ms) without degrading T (e.g., inlining function calls and reimplementing stdlib data structures). Then you really have to sacrifice clarity for efficiency. But be sure of the following:

  1. This is a last resort, when all the other options have failed.
  2. The code sections where T is traded for R are well isolated.
  3. There are few such sections.
  4. They are well documented.

Summary

Here is the mnemonic for good code:

T↓ R<R0

Optimize T, keep an eye on R. Your team will thank you.

 Subscribe to keep up with new posts.