-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Reduce compression memory use with map[string]uint16 #852
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
Conversation
map[string]uint16 uses 25% less memory per-entry than a map[string]int (16+2)/(16+8) = 0.75. All entries in the compression map are bound by maxCompressionOffset which is 14-bits and fits within a uint16.
Codecov Report
@@ Coverage Diff @@
## master #852 +/- ##
==========================================
+ Coverage 57.96% 58.05% +0.08%
==========================================
Files 42 42
Lines 10675 10690 +15
==========================================
+ Hits 6188 6206 +18
+ Misses 3398 3396 -2
+ Partials 1089 1088 -1
Continue to review full report at Codecov.
|
[ Quoting <notifications@github.com> in "[miekg/dns] Reduce compression memo..." ]
This PR switches the packing code to use a `map[string]uint16` for storing compression pointers while keeping support for external callers who pass in a `map[string]int`. This reduces the per-entry memory consumption of the compression map by 25%. (`(16+2)/(16+8) = 0.75`).
`compressionMap` is passed quite specifically as a value rather than a pointer because `RR.pack` is an interface method call which would cause it to escape and be heap allocated if it were a pointer. As maps are internally represented by a pointer to the runtime's `hmap` struct, the size of `compressionMap` is just 16-bytes anyway.
The benchmarks show a notable improvement in both memory use (alloc/op) and performance (time/op) for packing messages where multiple records are present.
```
name old time/op new time/op delta
MsgLengthPack-12 1.41µs ± 9% 1.46µs ±10% ~ (p=0.353 n=10+10)
PackDomainName-12 128ns ± 0% 137ns ± 1% +6.72% (p=0.000 n=6+10)
PackA-12 39.0ns ± 1% 40.1ns ± 1% +2.69% (p=0.000 n=8+8)
PackMX-12 69.6ns ± 1% 72.4ns ± 1% +4.05% (p=0.000 n=10+9)
PackAAAAA-12 37.9ns ± 1% 40.0ns ± 1% +5.68% (p=0.000 n=10+9)
PackMsg-12 1.01µs ± 5% 0.95µs ± 1% -5.85% (p=0.000 n=10+10)
PackMsgOnlyQuestion-12 168ns ± 0% 176ns ± 1% +4.94% (p=0.000 n=6+10)
PackMsgMassive-12 67.8µs ±10% 55.1µs ±10% -18.70% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
MsgLengthPack-12 576B ± 0% 528B ± 0% -8.33% (p=0.000 n=10+10)
PackDomainName-12 0.00B 0.00B ~ (all equal)
PackA-12 0.00B 0.00B ~ (all equal)
PackMX-12 0.00B 0.00B ~ (all equal)
PackAAAAA-12 0.00B 0.00B ~ (all equal)
PackMsg-12 256B ± 0% 208B ± 0% -18.75% (p=0.000 n=10+10)
PackMsgOnlyQuestion-12 0.00B 0.00B ~ (all equal)
PackMsgMassive-12 23.1kB ± 0% 19.0kB ± 0% -17.88% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
MsgLengthPack-12 3.00 ± 0% 3.00 ± 0% ~ (all equal)
PackDomainName-12 0.00 0.00 ~ (all equal)
PackA-12 0.00 0.00 ~ (all equal)
PackMX-12 0.00 0.00 ~ (all equal)
PackAAAAA-12 0.00 0.00 ~ (all equal)
PackMsg-12 2.00 ± 0% 2.00 ± 0% ~ (all equal)
PackMsgOnlyQuestion-12 0.00 0.00 ~ (all equal)
PackMsgMassive-12 12.0 ± 0% 12.0 ± 0% ~ (all equal)
```
Looking at these benchmarks are the skewed to larger messages? 'Cause most DNS
message are still small (less than 10 RRs)
|
Only If you look at the benchmarks, the increases are on the order of a few nanoseconds (and I believe come solely down to an extra few |
This PR switches the packing code to use a
map[string]uint16
for storing compression pointers while keeping support for external callers who pass in amap[string]int
. This reduces the per-entry memory consumption of the compression map by 25%. ((16+2)/(16+8) = 0.75
).compressionMap
is passed quite specifically as a value rather than a pointer becauseRR.pack
is an interface method call which would cause it to escape and be heap allocated if it were to be a pointer. As maps are internally represented by a pointer to the runtime'shmap
struct, the size ofcompressionMap
is only 16-bytes anyway.The benchmarks show a notable improvement in both memory use (alloc/op) and performance (time/op) for packing messages where multiple records are present.
Updates #652 (see #652 (comment)).
Edit: This is similar to #820 but for packing.