Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve TCPDialer by sync.map instead of map+mutex #1106

Merged
merged 1 commit into from Sep 20, 2021
Merged

feat: improve TCPDialer by sync.map instead of map+mutex #1106

merged 1 commit into from Sep 20, 2021

Conversation

tylitianrui
Copy link
Contributor

No description provided.

@erikdubbelboer
Copy link
Collaborator

The downside of sync.Map is that it requires two allocations instead of one:
https://play.golang.org/p/RVUVvngcHFi
vs
https://play.golang.org/p/OW7hGm0J1JN

Also this mutex isn't very much in contention. So I don't think we should do this.

@tylitianrui
Copy link
Contributor Author

The downside of sync.Map is that it requires two allocations instead of one:
https://play.golang.org/p/RVUVvngcHFi
vs
https://play.golang.org/p/OW7hGm0J1JN

Also this mutex isn't very much in contention. So I don't think we should do this.

yes, sync.map requires more memory allocation than map , because of its downside implement . tcpAddrEntry.tcpAddrsMap is a cache ( read more , write less ) of net.TCPAddr . so i think we should focus on cache-read more than cache-write

  • read

syncMap read:

var syncMap sync.Map
func BenchmarkSyncMap(b *testing.B) {
	syncMap.Store("example.com:443", &tcpAddrEntry{})
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			syncMap.Load("example.com:443")
		}
	})
}

benchmark

goos: darwin
goarch: amd64
pkg: github.com/valyala/fasthttp
BenchmarkSyncMap
BenchmarkSyncMap-8   	173760667	         7.35 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/valyala/fasthttp	2.218s

Map read:

var (
	mu sync.Mutex
	m  = make(map[string]*tcpAddrEntry)
)

func BenchmarkMap(b *testing.B) {
	m["example.com:443"] = &tcpAddrEntry{}
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			mu.Lock()
			_ = m["example.com:443"]
			mu.Unlock()
		}
	})
}

benchmark

goos: darwin
goarch: amd64
pkg: github.com/valyala/fasthttp
BenchmarkMap
BenchmarkMap-8   	17126959	        69.7 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/valyala/fasthttp	1.525s

when fasthttp.Dial is call in concurrent gorountine, as it faces me in real work , Map + mutex is not a better choice . when not in concurrency , Map + mutex is better.

@erikdubbelboer
Copy link
Collaborator

Since the extra allocation isn't in a hot path and it makes the cache slightly faster I'll merge it.

@erikdubbelboer erikdubbelboer merged commit 711e421 into valyala:master Sep 20, 2021
@erikdubbelboer
Copy link
Collaborator

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants