-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Properly calculate compressed message lengths #833
Conversation
This wasn't used anywhere but TestCompressionLenSearch, and was very wrong.
This replaces the confusing and complicated compressionLenSlice function.
This leaves the len() functions unused and they'll soon be removed. This also fixes the off-by-one error of compressedLen when a (Q)NAME is ".".
This eliminates the need to loop over the domain name twice when we're compressing the name.
This was a mistake.
These are the only RRs with multiple compressible names within the same RR, and they were previously broken.
It also handles the length of uncompressed domain names.
This should allow us to avoid the call overhead of compressionLenMapInsert in certain limited cases and may result in a slight performance increase. compressionLenMapInsert still has a maxCompressionOffset check inside the for loop.
This better reflects that it also calculates the uncompressed length.
They're both testing the same thing.
Codecov Report
@@ Coverage Diff @@
## master #833 +/- ##
==========================================
+ Coverage 57.6% 57.94% +0.33%
==========================================
Files 43 42 -1
Lines 10839 10661 -178
==========================================
- Hits 6244 6177 -67
+ Misses 3505 3396 -109
+ Partials 1090 1088 -2
Continue to review full report at Codecov.
|
I had a quick look, it seems reasonable, and removing my crappy hacks is good news ;) |
compressionLenSearch does everything compressionLenMapInsert did anyway.
The last two commits worsened the performance of domainNameLen noticably, this change restores it's original performance. name old time/op new time/op delta MsgLength-12 550ns ±13% 510ns ±21% ~ (p=0.050 n=10+10) MsgLengthNoCompression-12 26.9ns ± 2% 27.0ns ± 1% ~ (p=0.198 n=9+10) MsgLengthPack-12 2.30µs ±12% 2.26µs ±16% ~ (p=0.739 n=10+10) MsgLengthMassive-12 32.9µs ± 7% 32.0µs ±10% ~ (p=0.243 n=9+10) MsgLengthOnlyQuestion-12 9.60ns ± 1% 9.20ns ± 1% -4.16% (p=0.000 n=9+9)
[ Quoting <notifications@github.com> in "Re: [miekg/dns] Properly calculate ..." ]
I had a quick look, it seems reasonable, and removing my crappy hacks is good news ;)
I'll try to bench the performance effects in Consul once merged
Why not before? ;-)
/Miek
…--
Miek Gieben
|
this looks reasonable; I'll have to do a local checkout to take a closer look though |
This was introduced when resolving merge conflicts.
This entirely replaces the rather hacky and very confusing dance done in
compressionLenSlice
, with a new approach that is far more like how packing is performed. It fixes a number of different bugs (some listed at the end).The new code has two allocations that aren't actually needed, but are hard to avoid. (
MsgLength
&MsgLengthMassive
should have 0 and 9 allocations respectively). The problem is thatcompression map[string]struct{}
is passed toRR.len
whereRR
is an interface. This interacts badly with Golang's escape analysis (see golang/go#19361 and https://npat-efault.github.io/programming/2016/10/10/escape-analysis-and-interfaces.html), forcing the map to be heap allocated instead of stack allocated. It is possible to force these to be devirtualised by using a massive type switch statement, this worsens performance overall forMsgLengthMassive
while eliminating the loss forMsgLength
.The performance loss in
MsgLengthNoCompression
&MsgLengthOnlyQuestion
is (I believe) due to the call todomainNameLen
which can't be inlined currently. Though this is unfortunate, the overhead is necessary as it fixes a bug whereLen
could previously be off by one for uncompressed messages. (See the existingTestMsgLength2
that is now fixed). Inlining changes are coming to go1.12 so this can be revisited then and it may be possible to recover this performance loss.Some of the benchmarks below (like
LenLabels
andMuxMatch
) are just noise (although I don't quite understand how they survived through benchstat and ten runs), but they could come down to the compiler laying out code differently and cache interactions. TLDR; they're a distraction.When taken along with #820,
MsgLengthMassive
is now twice as fast, with half the allocated bytes and 92% fewer allocations.$ benchstat {old,new}.bench
Updates #709
Fixes #821
Fixes #824
Closes #826
Fixes #829
/cc @pierresouchay (who changed much of this in #668).