📜 ⬆️ ⬇️

The rules of good taste from Linus Torvalds. Making code faster, easier and more understandable.

“Taste is the ability to judge the beautiful”
I. Kant

Dirk Hondel, one of those who stood at the origins of Linux, once said about Linux creator Linus Torvalds: “Linus is not only a brilliant programmer: he has good taste. Torvalds finds simple and reasonable solutions to problems, knows how to "sort through everything." Complicated things he makes simple. In my opinion, this is the main difference between an excellent programmer and just a good one. ”

image

In a recent interview , about the 14th minute, Linus Torvalds touched on the theme of "good taste in programming." Good taste? The presenter asked him to dwell on this in more detail, and Linus, who came not empty-handed, showed a couple of slides.

At first, an example of bad taste in programming was demonstrated, so that against its background one could see better the merits of a higher quality code.


An example of bad taste in programming
')
This is a C function that removes objects from a linked list. It consists of 10 lines of code.

Linus called attention to the if control at the bottom of the function. It was with this fragment that he was especially displeased.

I paused the video and carefully reviewed the slide. I recently wrote something like that. Basically, Linus said that I have a bad taste. Swallowing a grudge, I continued to watch the video.

I have already come across the fact that Linus explained to the audience. Namely, the point was that when deleting objects from a linked list, two cases need to be considered. The first is when the object is somewhere in the middle of the list. The second is for the object at the top of the list. This approach forces the use of an if construct and leads to writing tasteless code.

But, if Linus himself recognizes the need to use a conditional operator, why doesn’t he like this approach?

Then he showed the audience the second slide. It was an example of the same function, but this time written with taste.


An example of good taste in programming

The same as in the previous example was done in ten lines of code, now fits into four.
But the length of the program text itself is not particularly important. The approach that led to the appearance of a conditional operator at the end of the first example is important. In the new code, additional conditions do not need to be checked. The code has been redesigned so that the same approach is used to remove the element from the middle of the list, and to delete the first element.

Linus explained the new code, said that the most important thing is to eliminate the border case, after which the conversation switched to another topic.

Reflections on good taste in programming


For a while I reflected on the example. Linus was right. The second fragment is much better. If it were a test for distinguishing between good and bad taste in programming, I would have failed this test. The idea that you can do without this unfortunate condition has never crossed my mind. And I wrote many times like this, because I often work with linked lists.

Perhaps the main value of the above example is not even that it demonstrates a good way to remove items from a linked list. The main thing here is that this example makes you think about the fact that the code you wrote, the implementation of small algorithms scattered around the program, can be improved in ways that you did not even realize.

It was to this idea that I paid special attention when I decided to revise the texts of my fresh project. Perhaps this is fate, but my program is also written in C.

As far as I understand, the focus of the issue of good taste in programming is the elimination of borderline cases, which tend to appear in the code as conditional statements. Good taste in programming is expressed, therefore, in reducing the number of conditions that have to be tested.
I want to talk about one successful example of improving my code.

Initialization of the edges of the grid with taste


Below is the algorithm that I wrote to initialize the elements along the edges of the grid, which is represented as a multidimensional array: grid[rows][cols] .

The purpose of this code was only to initialize the values ​​for elements that are located on the edges - that is, I was interested in the upper and lower lines, and the right and left columns.

In order to do this, I, in the original version of the program, went through a loop on each element of the grid, and, using a conditional operator, checked whether it was on the edge. Here's what it looked like:

 for (r = 0; r < GRID_SIZE; ++r) { for (c = 0; c < GRID_SIZE; ++c) { //   if (r == 0) grid[r][c] = 0; //   if (c == 0) grid[r][c] = 0; //   if (c == GRID_SIZE - 1) grid[r][c] = 0; //   if (r == GRID_SIZE - 1) grid[r][c] = 0; } } 

Although everything worked as it should, it was clear that the code was far from perfect. Namely, here are the main problems of this fragment:

  1. The code is too complicated. Using four conditional statements in two nested loops looks awkward.

  2. The code is ineffective. Assuming the GRID_SIZE variable is set to 64, the body of the inner loop will execute 4096 times just to find the 256 elements at the edges.

Linus would probably agree that this code cannot be attributed to samples of good taste.

Fiddling with the program for some time, I was able to reduce the complexity of the algorithm, the implementation of which now contained only one for loop, which contained four conditions. It was a slight improvement in terms of reducing the complexity of the code structure, but a serious one in performance. Now, only 256 loop passes are performed, one for each element located on the edge. Here is how the same fragment looked after the improvement.

 for (i = 0; i < GRID_SIZE * 4; ++i) { //   if (i < GRID_SIZE) grid[0][i] = 0; //   else if (i < GRID_SIZE * 2) grid[i - GRID_SIZE][GRID_SIZE - 1] = 0; //   else if (i < GRID_SIZE * 3) grid[i - (GRID_SIZE * 2)][0] = 0; //   else grid[GRID_SIZE - 1][i - (GRID_SIZE * 3)] = 0; } 

Got better? Yes. But it all looks just disgusting. This code is not one that can be understood at a glance. Only this one made me move on.

I continued to experiment, wondered if it was possible to improve something else. The answer was unequivocal: "Yes, you can." And what I finally came to was so strikingly simple and elegant that, frankly speaking, I could not believe that in order to figure this out, I had to spend so much time.

Here's what I did. There is only one cycle and no conditional statements. Moreover, the loop body is executed only 64 times. This option is much simpler and more productive than the first.

 for (i = 0; i < GRID_SIZE; ++i) { //   grid[0][i] = 0; //   grid[GRID_SIZE - 1][i] = 0; //   grid[i][0] = 0; //   grid[i][GRID_SIZE - 1] = 0; } 

In this code, four different boundary elements are initialized at each loop iteration. The code is simple and very efficient in terms of performance. Its easy to read. This option does not go to any comparison with the first and even with the second.

As a result, I was absolutely satisfied with the results.

Do I have a taste for programming?


And so, now I am a programmer whose code meets the rules of good taste?

I would like to hope that this is so, but not because I was able to remake the unfortunate part of my program, which I showed above, and others, too, which I did not include in the article. The thing is that the manifestation of good taste in programming is more than a piece of text. Linus himself said that the example he cited was too small to properly illustrate his point of view.

I think Linus meant that developers who have a “good taste for programming” differ from others in that they take the time to think about what they create before they start writing code.

They define the boundaries of the components with which they work, and how these components interact. They strive to make sure that everything fits together well, they try to achieve the grace of the code and the process of its execution.

The result of this approach is similar to the code that Linus brought, and to mine, too, only on a different, larger scale.

And how can you apply the concept of "good taste" in your projects?

Source: https://habr.com/ru/post/313836/


All Articles