Skip to content

funcr: Move kvlist sanitization to entry-points #110

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

Merged
merged 1 commit into from
Oct 13, 2021

Conversation

thockin
Copy link
Contributor

@thockin thockin commented Oct 11, 2021

This is more comprehensible and makes upcoming changes easier. Also
include a value snippet in non-string keys.

Fixes #106

funcr/funcr.go Outdated
kvList = append(kvList, "<no-value>")
}
for i := 0; i < len(kvList); i += 2 {
_, ok := kvList[i].(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type assertion now needs to be done twice. I was wondering whether this is measurable, so I ran the benchmarks before and after:

$GOPATH/bin/benchstat /tmp/master /tmp/pr
name                            old time/op    new time/op    delta
DiscardLogInfoOneArg-36           93.8ns ± 2%    95.1ns ± 2%    ~     (p=0.095 n=10+9)
DiscardLogInfoSeveralArgs-36       238ns ± 1%     238ns ± 0%    ~     (p=0.984 n=10+9)
DiscardLogInfoWithValues-36        241ns ± 1%     239ns ± 0%  -0.69%  (p=0.000 n=10+10)
DiscardLogV0Info-36                239ns ± 0%     240ns ± 1%    ~     (p=0.062 n=9+10)
DiscardLogV9Info-36                241ns ± 0%     239ns ± 1%  -1.07%  (p=0.000 n=10+10)
DiscardLogError-36                 260ns ± 0%     264ns ± 0%  +1.67%  (p=0.000 n=10+9)
DiscardWithValues-36               119ns ± 1%     116ns ± 2%  -2.91%  (p=0.000 n=10+10)
DiscardWithName-36                2.34ns ± 0%    2.34ns ± 0%    ~     (p=0.104 n=8+9)
FuncrLogInfoOneArg-36             1.15µs ± 6%    1.14µs ± 3%    ~     (p=0.726 n=10+10)
FuncrJSONLogInfoOneArg-36         1.31µs ± 5%    1.32µs ± 4%    ~     (p=0.493 n=10+10)
FuncrLogInfoSeveralArgs-36        2.63µs ± 2%    2.63µs ± 5%    ~     (p=0.968 n=9+10)
FuncrJSONLogInfoSeveralArgs-36    2.82µs ± 5%    2.82µs ± 3%    ~     (p=0.671 n=10+10)
FuncrLogInfoWithValues-36         2.74µs ± 3%    2.77µs ± 4%    ~     (p=0.324 n=10+10)
FuncrJSONLogInfoWithValues-36     2.89µs ± 3%    3.03µs ± 1%  +4.64%  (p=0.000 n=10+9)
FuncrLogV0Info-36                 2.59µs ± 6%    2.64µs ± 4%    ~     (p=0.315 n=10+10)
FuncrJSONLogV0Info-36             2.81µs ± 6%    2.82µs ± 5%    ~     (p=0.549 n=9+10)
FuncrLogV9Info-36                  255ns ± 7%     256ns ± 1%    ~     (p=0.705 n=9+10)
FuncrJSONLogV9Info-36              237ns ±14%     256ns ± 1%  +8.02%  (p=0.000 n=10+10)
FuncrLogError-36                  2.99µs ± 7%    3.07µs ± 6%    ~     (p=0.172 n=10+10)
FuncrJSONLogError-36              3.28µs ± 8%    3.26µs ± 4%    ~     (p=0.971 n=10+10)
FuncrWithValues-36                1.33µs ± 3%    1.35µs ± 3%    ~     (p=0.109 n=10+10)
FuncrWithName-36                   190ns ± 1%     186ns ± 1%  -1.93%  (p=0.000 n=10+10)
FuncrWithCallDepth-36              178ns ± 1%     178ns ± 1%    ~     (p=0.098 n=10+9)

I'm not sure what to make of these numbers. Why are some benchmarks getting better? Looks like noise.

@thockin
Copy link
Contributor Author

thockin commented Oct 12, 2021 via email

@pohly
Copy link
Contributor

pohly commented Oct 12, 2021

I think this change makes sense and we should merge this even if there is a small slowdown, I'm just surprised that this isn't showing up as a small slowdown consistently.

One more idea: would it make sense to represent a sanitized key/value list differently so that the second type assertion during usage becomes unnecessary? Something like []struct {key string; value interface{}}.

This would make the API in #111 simpler because instead of just documenting that the []interface{} slice is sanitized, we can put that into the type.

On the other hand, a slice that is already sane cannot be passed through. We would have to do allocations in all cases. This probably is a showstopper.

@thockin
Copy link
Contributor Author

thockin commented Oct 12, 2021 via email

@pohly
Copy link
Contributor

pohly commented Oct 12, 2021

So we're quibbling over 10 ns out of 600.

Definitely not worth it. I'm more interested in a sane API (different type, if possible) and understanding the benchmark results: are the results reliable or too noisy?

For example, why is BenchmarkFuncrJSONLogInfoWithValues with double cast faster (1271 ns/op) than without it (1321 ns/op)?

@pohly
Copy link
Contributor

pohly commented Oct 12, 2021

I re-ran with -benchtime=5s -count=5 and compared with benchstat. It no longer shows a significant difference with and without this commit:

name                            old time/op  new time/op  delta
FuncrLogInfoOneArg-36           1.13µs ± 1%  1.14µs ± 1%   ~     (p=0.198 n=5+5)
FuncrJSONLogInfoOneArg-36       1.32µs ± 3%  1.34µs ± 3%   ~     (p=0.206 n=5+5)
FuncrLogInfoSeveralArgs-36      2.61µs ± 1%  2.58µs ± 3%   ~     (p=0.643 n=5+5)
FuncrJSONLogInfoSeveralArgs-36  2.81µs ± 2%  2.78µs ± 2%   ~     (p=0.222 n=5+5)
FuncrLogInfoWithValues-36       2.72µs ± 2%  2.75µs ± 1%   ~     (p=0.421 n=5+5)
FuncrJSONLogInfoWithValues-36   2.97µs ± 2%  2.96µs ± 2%   ~     (p=0.841 n=5+5)

Let's merge once we are happy with the resulting API in PR #111

@thockin
Copy link
Contributor Author

thockin commented Oct 12, 2021

I retooled anyway - this is almost as simple in the next commit and marginally better here. Difference is noise.

before:

$ go test -benchtime=5s -bench='Funcr.*LogInfo' ./benchmark/
goos: linux
goarch: amd64
pkg: github.com/go-logr/logr/benchmark
cpu: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
BenchmarkFuncrLogInfoOneArg-6            	10282844	       585.9 ns/op
BenchmarkFuncrJSONLogInfoOneArg-6        	 8646552	       670.4 ns/op
BenchmarkFuncrLogInfoSeveralArgs-6       	 5214578	      1128 ns/op
BenchmarkFuncrJSONLogInfoSeveralArgs-6   	 4656568	      1287 ns/op
BenchmarkFuncrLogInfoWithValues-6        	 5011843	      1198 ns/op
BenchmarkFuncrJSONLogInfoWithValues-6    	 4593704	      1307 ns/op
PASS
ok  	github.com/go-logr/logr/benchmark	42.002s

after:

$ go test -benchtime=5s -bench='Funcr.*LogInfo' ./benchmark/
goos: linux
goarch: amd64
pkg: github.com/go-logr/logr/benchmark
cpu: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
BenchmarkFuncrLogInfoOneArg-6            	10246636	       586.2 ns/op
BenchmarkFuncrJSONLogInfoOneArg-6        	 8920521	       677.5 ns/op
BenchmarkFuncrLogInfoSeveralArgs-6       	 5120431	      1173 ns/op
BenchmarkFuncrJSONLogInfoSeveralArgs-6   	 4696465	      1227 ns/op
BenchmarkFuncrLogInfoWithValues-6        	 5499103	      1192 ns/op
BenchmarkFuncrJSONLogInfoWithValues-6    	 4611615	      1302 ns/op
PASS
ok  	github.com/go-logr/logr/benchmark	42.553s

@thockin
Copy link
Contributor Author

thockin commented Oct 12, 2021

ugh, I might have messed up
hold

@thockin
Copy link
Contributor Author

thockin commented Oct 12, 2021

OK, fixed messup.

before:

$ go test -benchtime=5s -bench='Funcr.*LogInfo' ./benchmark/
goos: linux
goarch: amd64
pkg: github.com/go-logr/logr/benchmark
cpu: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
BenchmarkFuncrLogInfoOneArg-6            	10216773	       584.1 ns/op
BenchmarkFuncrJSONLogInfoOneArg-6        	 8863647	       679.9 ns/op
BenchmarkFuncrLogInfoSeveralArgs-6       	 5012000	      1187 ns/op
BenchmarkFuncrJSONLogInfoSeveralArgs-6   	 4650787	      1287 ns/op
BenchmarkFuncrLogInfoWithValues-6        	 5012245	      1205 ns/op
BenchmarkFuncrJSONLogInfoWithValues-6    	 4898595	      1274 ns/op
PASS
ok  	github.com/go-logr/logr/benchmark	42.457s

after:

$ go test -benchtime=5s -bench='Funcr.*LogInfo' ./benchmark/
goos: linux
goarch: amd64
pkg: github.com/go-logr/logr/benchmark
cpu: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
BenchmarkFuncrLogInfoOneArg-6            	10264160	       585.1 ns/op
BenchmarkFuncrJSONLogInfoOneArg-6        	 8903834	       673.6 ns/op
BenchmarkFuncrLogInfoSeveralArgs-6       	 5090527	      1185 ns/op
BenchmarkFuncrJSONLogInfoSeveralArgs-6   	 4555240	      1287 ns/op
BenchmarkFuncrLogInfoWithValues-6        	 4975938	      1209 ns/op
BenchmarkFuncrJSONLogInfoWithValues-6    	 4539871	      1310 ns/op
PASS
ok  	github.com/go-logr/logr/benchmark	42.227s

noise.

Ready to merge at your whim, IMO.

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
This is more comprehensible and makes upcoming changes easier.   Also
include a value snippet in non-string keys.
@pohly pohly merged commit e39a01e into go-logr:master Oct 13, 2021
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.

funcr: non-string key handling
2 participants