In-depth Tracing
This is a similar example to the previous version.
The special thing here is Regions
in trace.
It helps to identify possible bottle necks in the program.
The way of trace reporting remains the same.
Except, now we have ability to locate time taking pieces correctly.
Here is how we add Regions
in code:
...
r3 := trace.StartRegion(context.Background(), "Read from Goroutines")
...
r3.End()
...
Now to display the traces:
go tool trace t.out
This time try the Link:
User-defined regions
In the list of options.
Here you can clearly see the various locations in the code and how much time they are taking.
Optimization
In our example we have a in
channel where all the goroutines try to
write their outputs.
Now buffering this channel can reduce the waiting time for most goroutines.
Though its a easy to see, but one can observe the changes from the
differences it make in the User-defined regions
plots.
...
in := make(chan string, runtime.NumCPU()*100)
...
This one is the most optimal.
After this we try to over-optimize by adding more channels.
...
in := make(chan string, runtime.NumCPU()*1000)
...
This causes the system to get loaded.
Since we are allocating more buffer for channels than we need.
This intern slows down the main program thread.
It helps to find the best suited path among all solutions.
Conclusion
Using Regions
helps to analyse the code with clear boundaries.
It also helps to isolate problem areas.
And look at what optimization efforts are effecting exactly.
It would be a very helpful tool in debugging bigger and complex
system written in golang
.
Another important point to note is that if we build the code
the size and performance hit because of trace is very little or insignificant.