Open mtchuyen opened 2 years ago
Small number change will affect benchmark results
https://groups.google.com/g/golang-nuts/c/WtkYMKz46es
The benchmark code: https://play.golang.org/p/IqVnVa5x9qp
When N == 16384, the benchmark result:
Benchmark_Insert-4 134622 8032 ns/op 32768 B/op 1 allocs/op Benchmark_Insert2-4 132049 8201 ns/op 32768 B/op 1 allocs/op
When N == 16385, the benchmark result:
Benchmark_Insert-4 118677 9374 ns/op 40960 B/op 1 allocs/op Benchmark_Insert2-4 136845 7744 ns/op 40960 B/op 1 allocs/op
=== 16384+16384= 32768 and 16385+16384= 32769. 32768 bytes will be allocated on a memory block in the 32768 size class, which is the largest size class. 32769 bytes will be allocated on 5 pages (each page is 8192 bytes).
But the implementations of Insert and Insert2 are very similar, the allocation algorithms for them should be the same (for a specified number). So it is weird the number change causes positive impact for one implementation,effect but negative impact for the other.
https://coralogix.com/blog/optimizing-a-golang-service-to-reduce-over-40-cpu/
Optimize
https://artem.krylysov.com/blog/2017/03/13/profiling-and-optimizing-go-web-applications/
https://towardsdev.com/golang-writing-memory-efficient-and-cpu-optimized-go-structs-62fcef4dbfd0
Trước khi đọc bài này, cần đọc phần cơ bản:
Golang Field Alignment: https://medium.com/@didi12468/golang-field-alignment-2e657e87668a
The number of bytes occupied by each embedded type of Go (64-bit machine)
[nob.1]: Number of byte of String: 16 bytes
type stringStruct struct {
str unsafe.Pointer
len int
}
str
len
[nob.2]: Number of byte of String: 24 bytes
type slice struct {
array unsafe.Pointer
len int
cap int
}
str
len
cap
Bài viết được viết lại:
https://viblo.asia/p/golang-memory-cac-loai-type-Qbq5Q7rRZD8
Không chỉ gây ảnh hưởng tới memory, còn ảnh hưởng tới cả CPU, và thời gian tính toán 1 phép tính: Xem ở When IO-bound Hides Inside CPU
https://medium.com/scum-gazeta/golang-simple-optimization-notes-70bc64673980
If you need to add items to an array, the go-to option is “append”. For example:
for _, v := range inputArray {
myArray = append(myArray, v)
}
However, this can be slow on large arrays, because append will keep needing to increase the size of “myArray” to accommodate the new values. A better way to it is to specify the length of the array first, then direct assign each value:
myArray := make([]int, len(inputArray))
for i, v := range inputArray {
myArray[i] = v
}
}
There is a third option which I like even better, and that is to combine the two! To me, it is slightly more readable but also doesn't have the speed penalty as you are assigning the size at the start.
myArray := make([]int, 0, len(inputArray))
for _, v := range inputArray {
myArray = append(myArray, v)
}
Here you set the size of the array as 0, but the max size as the length of the input array. So append doesn't need to resize as it goes. If you compare the times on an array of 100 million integers you can see the speed difference:
normal array append took 3782.1423ms
presized array took 549.8333ms
presized array append took 685.9402ms
How to Optimize A Golang Application Which Has More Than 100 Million Objects at Peak?
https://groups.google.com/g/golang-nuts/c/ni1mRfenItM
Implementing The Fieldalignment Bundle in Go
https://medium0.com/@switchupcb/implementing-the-fieldalignment-bundle-in-go-1f725302a6dc
The fieldalignment bundle is a technique that you can use to minimize the amount of memory your application uses during runtime. This can result in a performance improvement due to the semantics of the Go Garbage Collector.
Struct Padding
A system’s architecture (32-bit, 64-bit) defines
bits
) of each word (Call: first factor)The first factor serves as the basis for the size of primitive types (i.e string, int, uint, etc) in the Go programming language. As an example, the sizes of basic types can be found in go/types/sizes.go:131.
The second factor serves as the basis for struct padding, which aligns the fields of structs to addresses in memory.
word
size (struct's size is a multiple of a valid word size) (i.e:8 bytes * multiple on 64-bit systems
)For more information on memory alignment, read Memory Layouts (Go) and Dealing With Maligned Structs.
Field-Alignment
Fieldalignment is the process of aligning the fields in Go structs in order to minimize the size of the struct (in memory).
In the Go programming language, issues with fieldalignment can be fixed using the fieldalignment tool which is installed using:
Using the
fieldalignment
command will tell you where mis-aligned fields are in your program.-fix
flag will fix these issues for you while using-json
will print out diagnostics in the JSON format.As a WARNING, running
fieldalignment -fix ./...
may remove comments from your fields due to the underlying difficulty in manipulating free-floating comments within the Go Abstract Syntax Tree.What are the benefits?
The benefits of fieldalignment are observed in bulk.
If your application saves
8 bytes
per struct through fieldalignment, this will save you 8 MB of memory for every struct that is used within 1 MILLION requests. That allows you to save money on memory resources, and may even reduce the amount of peaks within the Go Garbage Collector (which improves performance over time
).To be specific, Go uses a Stop The World Garbage Collector which triggers at a target heap size. Garbage Collector latency can be reduced by maintaining the smallest heap possible at a consistent pace.
Caveat
Fieldalignment can result in performance degradation as a compact field order can cause two variables (in separate goroutines) that are updated at the same time to occupy the same CPU cache line: This results in a form of memory contention called false sharing. When false sharing occurs, the first variable that is being updated is forced to reload a CPU cache block even though it’s not required. Thus, both goroutines updating each variable are slowed down.
Bundle
In the context of software development, a bundle represents a collection of files or sources.
.go
file.Bundling can be achieved in Go by using the tool which is installed using:
Using the
bundle
command bundles the application into a single file.However, this can generate a file that contains collisions in its imports.
-import new=old flag
, but there are other cases that you have to fix manually.Implementing the Fieldalignment Bundle
The fieldalignment bundle technique involves bundling your source code, then fieldaligning it.