Skip to content

Commit b9d8729

Browse files
committed
sync.Pool
1 parent 7cc6f87 commit b9d8729

File tree

8 files changed

+239
-0
lines changed

8 files changed

+239
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module pool
2+
3+
go 1.18
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
type DbConnection struct {
9+
Host string
10+
DbName string
11+
User string
12+
Password string
13+
}
14+
15+
var connectionPool sync.Pool = sync.Pool{
16+
New: func() interface{} {
17+
return &DbConnection{
18+
Host: "localhost",
19+
DbName: "test",
20+
User: "root",
21+
Password: "root",
22+
}
23+
},
24+
}
25+
26+
func main() {
27+
28+
connection := connectionPool.Get().(*DbConnection)
29+
30+
fmt.Printf("%v\n", connection)
31+
32+
connectionPool.Put(connection)
33+
34+
connection = connectionPool.Get().(*DbConnection)
35+
36+
fmt.Printf("%v\n", connection)
37+
38+
connectionPool.Put(connection)
39+
40+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import "testing"
4+
5+
func BenchmarkWithoutPool(b *testing.B) {
6+
var connection *DbConnection
7+
b.ReportAllocs()
8+
b.ResetTimer()
9+
for i := 0; i < b.N; i++ {
10+
for i := 0; i < 10000; i++ {
11+
connection = &DbConnection{
12+
Host: "localhost",
13+
DbName: "test",
14+
User: "root",
15+
Password: "root",
16+
}
17+
18+
connection.DbName = "test"
19+
}
20+
}
21+
22+
}
23+
24+
func BenchmarkWithPool(b *testing.B) {
25+
var connection *DbConnection
26+
b.ReportAllocs()
27+
b.ResetTimer()
28+
for i := 0; i < b.N; i++ {
29+
for i := 0; i < 10000; i++ {
30+
connection = connectionPool.Get().(*DbConnection)
31+
connection.DbName = "test"
32+
connectionPool.Put(connection)
33+
}
34+
}
35+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module poolExample
2+
3+
go 1.18
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// https://medium.com/swlh/go-the-idea-behind-sync-pool-32da5089df72
2+
3+
package main
4+
5+
func main() {
6+
//RunMemoryUsageExample()
7+
RunNonBufferPoolExample()
8+
//RunBufferPoolExample()
9+
10+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
"time"
7+
)
8+
9+
func RunMemoryUsageExample() {
10+
11+
// Below is an example of using our PrintMemUsage() function
12+
// Print our starting memory usage (should be around 0mb)
13+
PrintMemUsage()
14+
15+
var overall [][]int
16+
for i := 0; i < 4; i++ {
17+
18+
// Allocate memory using make() and append to overall (so it doesn't get
19+
// garbage collected). This is to create an ever increasing memory usage
20+
// which we can track. We're just using []int as an example.
21+
a := make([]int, 0, 999999)
22+
overall = append(overall, a)
23+
24+
// Print our memory usage at each interval
25+
PrintMemUsage()
26+
time.Sleep(time.Second)
27+
}
28+
29+
// Clear our memory and print usage, unless the GC has run 'Alloc' will remain the same
30+
overall = nil
31+
PrintMemUsage()
32+
33+
// Force GC to clear up, should see a memory drop
34+
runtime.GC()
35+
PrintMemUsage()
36+
37+
}
38+
39+
func PrintMemUsage() {
40+
var m runtime.MemStats
41+
runtime.ReadMemStats(&m)
42+
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
43+
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
44+
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
45+
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
46+
fmt.Printf("\tNumGC = %v\n", m.NumGC)
47+
}
48+
49+
func bToMb(b uint64) uint64 {
50+
return b / 1024 / 1024
51+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"sync"
6+
)
7+
8+
var data = make([]byte, 10000)
9+
10+
var pool = sync.Pool{
11+
New: func() interface{} {
12+
return &bytes.Buffer{}
13+
},
14+
}
15+
16+
func RunBufferPoolExample() {
17+
18+
PrintMemUsage()
19+
for i := 0; i < 10_000; i++ {
20+
UseBufferWithPool()
21+
}
22+
//runtime.GC()
23+
PrintMemUsage()
24+
25+
}
26+
27+
func UseBufferWithPool() {
28+
buf := pool.Get().(*bytes.Buffer)
29+
buf.Write(data)
30+
buf.Reset()
31+
pool.Put(buf)
32+
}
33+
34+
func UseBuffer() {
35+
var buf bytes.Buffer
36+
buf.Write(data)
37+
}
38+
39+
func RunNonBufferPoolExample() {
40+
41+
PrintMemUsage()
42+
for i := 0; i < 10_000; i++ {
43+
UseBuffer()
44+
}
45+
//runtime.GC()
46+
PrintMemUsage()
47+
48+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package main
2+
3+
import (
4+
"sync"
5+
"testing"
6+
)
7+
8+
type DbConnection struct {
9+
DbName string
10+
UserId string
11+
Password string
12+
Timeout int
13+
}
14+
15+
var connectionPool = sync.Pool{
16+
New: func() any {
17+
return &DbConnection{
18+
DbName: "DbTest",
19+
UserId: "UserTest",
20+
Password: "PasswordTest",
21+
Timeout: 20,
22+
}
23+
},
24+
}
25+
26+
func BenchmarkWithoutPool(b *testing.B) {
27+
var p *DbConnection
28+
b.ReportAllocs()
29+
b.ResetTimer()
30+
for i := 0; i < b.N; i++ {
31+
for j := 0; j < 10000; j++ {
32+
p = &DbConnection{}
33+
p.Timeout = 45
34+
}
35+
}
36+
}
37+
38+
func BenchmarkWithPool(b *testing.B) {
39+
var p *DbConnection
40+
b.ReportAllocs()
41+
b.ResetTimer()
42+
for i := 0; i < b.N; i++ {
43+
for j := 0; j < 10000; j++ {
44+
p = connectionPool.Get().(*DbConnection)
45+
46+
connectionPool.Put(p)
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)