Rocky runs up the stairs
Hi, Habr. You probably remember me: I am Marko Kevac, a system programmer at Badoo. Recently, I stumbled upon a little story about how a newbie made a change in the Go language runtime. Despite the fact that this post is probably quite unexpectedly met in the Badoo hrabrablog, and many may say that it is trite and overwhelmed with naive joy, I believe that such stories demonstrate how friendly the Go community is with respect to all its members. . Therefore, translated it.
And in the post there are two interesting facts related to the insides of the language. Enjoy reading!
I have been writing open-source programs on Go for some time. And just recently I had the opportunity to write on Go and at work. I happily switched and became a real Go-developer.
Everything was fine until the last GopherCon conference took place, where they held a master class for those who want to contribute to the development of the language. And now, seeing how all these people commit the code to the main repository, I also wanted to do something. And just a couple of days later, Francesc Campoy recorded an excellent video in which he described in detail how to contribute to Go.
The desire to be a sacrament enveloped me. I had no idea what I could do, but decided to download the source code and compile it. And so began my journey along the road of the Go distributor.
I read the instructions for contributors and carried it out step by step. It didn’t happen immediately to sign the CLA, as the instructions were a bit clumsy. Actually, why not point this out and propose to fix it? This could be my first CL! Inspired, I created a ticket . But it turned out, I stepped on a standard novice rake. The problem has already been solved in the Tip, but I did not even guess to look.
Since everything was ready for me, I occasionally just walked through the standard library in search of things that would fix it. And since I’ve been programming on Go for several months now, I ran into parts of runtime that constantly surfaced during profiling. One of these parts is the fmt package. I decided to look at him carefully and see if something could be done about it. About an hour later, I came across something interesting.
The fmt_sbx
function in the fmt/format.go
starts as follows:
func (f *fmt) fmt_sbx(s string, b []byte, digits string) { length := len(b) if b == nil { // No byte slice present. Assume string s should be encoded. length = len(s) }
It was clear that len()
is called twice if b
is nil
, although most often one is enough. But if you move it to else
, then len()
will always be called only once. I decided to send CL about this to see what others say.
Just a couple of minutes later, Ian gave a rating of +2, and then Avelino - +1. I could not believe it!
But then something went wrong. Dave bet -1, and Martin too . He took a binary code dump and saw that there was no difference between the two options. The compiler was smart enough to make this small optimization. So in the end, I ended up in the red: else
badly affects the readability of the code, and there is no gain in performance.
This CL had to be abandoned ...
But I learned a lot. For example, about utilities like benchstat
and benchcmp
. Moreover, now I was familiar with the whole process and it cost me nothing to try again.
I soon learned that simple string concatenation is much faster than fmt.Sprintf()
. With this knowledge, I went looking for a “sacrifice,” and it didn't take long. I settled on the archive/tar
package. The formatPAXRecord
function in the archive/tar/strconv.go
contains the following code:
size := len(k) + len(v) + padding size += len(strconv.Itoa(size)) record := fmt.Sprintf("%d %s=%s\n", size, k, v)
After I changed the last line to record := fmt.Sprint(size) + " " + k + "=" + v + "\n"
, I saw a significant acceleration:
name old time/op new time/op delta FormatPAXRecord 683ns ± 2% 457ns ± 1% -33.05% (p=0.000 n=10+10) name old alloc/op new alloc/op delta FormatPAXRecord 112B ± 0% 64B ± 0% -42.86% (p=0.000 n=10+10) name old allocs/op new allocs/op delta FormatPAXRecord 8.00 ± 0% 6.00 ± 0% -25.00% (p=0.000 n=10+10)
The rest, as they say, is history. This time, Joe updated the code, and after a few minor fixes, it was frozen! Hooray! I contributed to the development of Go. I have gone from a mediocre open-source contributor to a contributor to the Go programming language.
This is far from the end. I begin to better understand the subtleties of the language and will continue to create CL every time I find something. Ten cups of tea to the masters of the Go-team for the fact that they so gracefully and tirelessly manage the development of such a complex project.
PS Well, for reference:
Source: https://habr.com/ru/post/336620/
All Articles