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

Replace toJsonMap function with a lazy value #107

Closed
chuwy opened this issue Oct 12, 2020 · 5 comments
Closed

Replace toJsonMap function with a lazy value #107

chuwy opened this issue Oct 12, 2020 · 5 comments

Comments

@chuwy
Copy link
Contributor

chuwy commented Oct 12, 2020

Given it's used by ordered many times - we can significantly improve performance by computing it only once:

def ordered: List[(String, Option[Json])] =
Event.parser.knownKeys.map(key => (key.name, toJsonMap.get(key.name)))

@benjben
Copy link
Contributor

benjben commented Oct 14, 2020

Before the rewrite, here are the results of benchmarking (with jmh:run -i 10 -wi 3 -f2 -t3) :

[info] # JMH version: 1.25
[info] # VM version: JDK 11.0.6, OpenJDK 64-Bit Server VM, 11.0.6+10-post-Debian-1bpo91
[info] # VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
[info] # VM options: <none>
[info] # Warmup: 3 iterations, 10 s each
[info] # Measurement: 10 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 3 threads, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered
[info] # Run progress: 0.00% complete, ETA 00:08:40
[info] # Fork: 1 of 2
[info] # Warmup Iteration   1: ≈ 10⁻³ ops/us
[info] # Warmup Iteration   2: ≈ 10⁻³ ops/us
[info] # Warmup Iteration   3: ≈ 10⁻³ ops/us
[info] Iteration   1: ≈ 10⁻³ ops/us
[info] Iteration   2: ≈ 10⁻³ ops/us
[info] Iteration   3: ≈ 10⁻³ ops/us
[info] Iteration   4: ≈ 10⁻³ ops/us
[info] Iteration   5: ≈ 10⁻³ ops/us
[info] Iteration   6: ≈ 10⁻³ ops/us
[info] Iteration   7: ≈ 10⁻³ ops/us
[info] Iteration   8: 0.001 ops/us
[info] Iteration   9: 0.001 ops/us
[info] Iteration  10: 0.001 ops/us
[info] # Run progress: 25.00% complete, ETA 00:06:32
[info] # Fork: 2 of 2
[info] # Warmup Iteration   1: ≈ 10⁻³ ops/us
[info] # Warmup Iteration   2: 0.001 ops/us
[info] # Warmup Iteration   3: ≈ 10⁻³ ops/us
[info] Iteration   1: 0.001 ops/us
[info] Iteration   2: 0.001 ops/us
[info] Iteration   3: 0.001 ops/us
[info] Iteration   4: 0.001 ops/us
[info] Iteration   5: 0.001 ops/us
[info] Iteration   6: 0.001 ops/us
[info] Iteration   7: 0.001 ops/us
[info] Iteration   8: 0.001 ops/us
[info] Iteration   9: 0.001 ops/us
[info] Iteration  10: 0.001 ops/us
[info] Result "com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered":
[info]   0.001 ±(99.9%) 0.001 ops/us [Average]
[info]   (min, avg, max) = (≈ 10⁻³, 0.001, 0.001), stdev = 0.001
[info]   CI (99.9%): [≈ 10⁻³, 0.001] (assumes normal distribution)
[info] # JMH version: 1.25
[info] # VM version: JDK 11.0.6, OpenJDK 64-Bit Server VM, 11.0.6+10-post-Debian-1bpo91
[info] # VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
[info] # VM options: <none>
[info] # Warmup: 3 iterations, 10 s each
[info] # Measurement: 10 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 3 threads, will synchronize iterations
[info] # Benchmark mode: Average time, time/op
[info] # Benchmark: com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered
[info] # Run progress: 50.00% complete, ETA 00:04:21
[info] # Fork: 1 of 2
[info] # Warmup Iteration   1: 6524.157 ±(99.9%) 3151.615 us/op
[info] # Warmup Iteration   2: 5658.176 ±(99.9%) 675.118 us/op
[info] # Warmup Iteration   3: 5859.169 ±(99.9%) 189.335 us/op
[info] Iteration   1: 5685.592 ±(99.9%) 774.390 us/op
[info] Iteration   2: 5579.917 ±(99.9%) 306.011 us/op
[info] Iteration   3: 5647.106 ±(99.9%) 392.849 us/op
[info] Iteration   4: 5763.273 ±(99.9%) 650.658 us/op
[info] Iteration   5: 5775.713 ±(99.9%) 494.140 us/op
[info] Iteration   6: 5732.225 ±(99.9%) 2641.175 us/op
[info] Iteration   7: 5249.234 ±(99.9%) 344.314 us/op
[info] Iteration   8: 4537.562 ±(99.9%) 64.047 us/op
[info] Iteration   9: 4482.543 ±(99.9%) 200.290 us/op
[info] Iteration  10: 4403.862 ±(99.9%) 185.006 us/op
[info] # Run progress: 75.00% complete, ETA 00:02:10
[info] # Fork: 2 of 2
[info] # Warmup Iteration   1: 7038.108 ±(99.9%) 2290.543 us/op
[info] # Warmup Iteration   2: 6060.794 ±(99.9%) 282.454 us/op
[info] # Warmup Iteration   3: 6143.986 ±(99.9%) 110.664 us/op
[info] Iteration   1: 6346.754 ±(99.9%) 246.708 us/op
[info] Iteration   2: 6491.202 ±(99.9%) 2625.066 us/op
[info] Iteration   3: 6381.568 ±(99.9%) 1226.350 us/op
[info] Iteration   4: 6570.449 ±(99.9%) 2968.226 us/op
[info] Iteration   5: 6372.206 ±(99.9%) 1110.280 us/op
[info] Iteration   6: 6325.100 ±(99.9%) 684.072 us/op
[info] Iteration   7: 6022.833 ±(99.9%) 373.478 us/op
[info] Iteration   8: 5453.750 ±(99.9%) 477.195 us/op
[info] Iteration   9: 5346.006 ±(99.9%) 527.296 us/op
[info] Iteration  10: 5256.194 ±(99.9%) 158.473 us/op
[info] Result "com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered":
[info]   5671.154 ±(99.9%) 574.776 us/op [Average]
[info]   (min, avg, max) = (4403.862, 5671.154, 6570.449), stdev = 661.913
[info]   CI (99.9%): [5096.379, 6245.930] (assumes normal distribution)
[info] # Run complete. Total time: 00:08:43
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark                       Mode  Cnt     Score     Error   Units
[info] BenchmarkAnalyticsSDK.ordered  thrpt   20     0.001 ±   0.001  ops/us
[info] BenchmarkAnalyticsSDK.ordered   avgt   20  5671.154 ± 574.776   us/op

@benjben
Copy link
Contributor

benjben commented Oct 14, 2020

And now with the lazy val :

[info] # JMH version: 1.25
[info] # VM version: JDK 11.0.6, OpenJDK 64-Bit Server VM, 11.0.6+10-post-Debian-1bpo91
[info] # VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
[info] # VM options: <none>
[info] # Warmup: 3 iterations, 10 s each
[info] # Measurement: 10 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 3 threads, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered
[info] # Run progress: 0.00% complete, ETA 00:08:40
[info] # Fork: 1 of 2
[info] # Warmup Iteration   1: 0.558 ops/us
[info] # Warmup Iteration   2: 0.593 ops/us
[info] # Warmup Iteration   3: 0.628 ops/us
[info] Iteration   1: 0.718 ops/us
[info] Iteration   2: 0.747 ops/us
[info] Iteration   3: 0.750 ops/us
[info] Iteration   4: 0.764 ops/us
[info] Iteration   5: 0.764 ops/us
[info] Iteration   6: 0.758 ops/us
[info] Iteration   7: 0.748 ops/us
[info] Iteration   8: 0.762 ops/us
[info] Iteration   9: 0.766 ops/us
[info] Iteration  10: 0.764 ops/us
[info] # Run progress: 25.00% complete, ETA 00:06:32
[info] # Fork: 2 of 2
[info] # Warmup Iteration   1: 0.649 ops/us
[info] # Warmup Iteration   2: 0.638 ops/us
[info] # Warmup Iteration   3: 0.687 ops/us
[info] Iteration   1: 0.691 ops/us
[info] Iteration   2: 0.714 ops/us
[info] Iteration   3: 0.712 ops/us
[info] Iteration   4: 0.706 ops/us
[info] Iteration   5: 0.680 ops/us
[info] Iteration   6: 0.707 ops/us
[info] Iteration   7: 0.710 ops/us
[info] Iteration   8: 0.705 ops/us
[info] Iteration   9: 0.705 ops/us
[info] Iteration  10: 0.692 ops/us
[info] Result "com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered":
[info]   0.728 ±(99.9%) 0.026 ops/us [Average]
[info]   (min, avg, max) = (0.680, 0.728, 0.766), stdev = 0.029
[info]   CI (99.9%): [0.703, 0.754] (assumes normal distribution)
[info] # JMH version: 1.25
[info] # VM version: JDK 11.0.6, OpenJDK 64-Bit Server VM, 11.0.6+10-post-Debian-1bpo91
[info] # VM invoker: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
[info] # VM options: <none>
[info] # Warmup: 3 iterations, 10 s each
[info] # Measurement: 10 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 3 threads, will synchronize iterations
[info] # Benchmark mode: Average time, time/op
[info] # Benchmark: com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered
[info] # Run progress: 50.00% complete, ETA 00:04:21
[info] # Fork: 1 of 2
[info] # Warmup Iteration   1: 4.553 ±(99.9%) 1.211 us/op
[info] # Warmup Iteration   2: 4.377 ±(99.9%) 0.218 us/op
[info] # Warmup Iteration   3: 4.350 ±(99.9%) 0.800 us/op
[info] Iteration   1: 4.201 ±(99.9%) 0.283 us/op
[info] Iteration   2: 4.368 ±(99.9%) 0.614 us/op
[info] Iteration   3: 4.219 ±(99.9%) 0.291 us/op
[info] Iteration   4: 4.215 ±(99.9%) 0.260 us/op
[info] Iteration   5: 4.286 ±(99.9%) 0.292 us/op
[info] Iteration   6: 4.184 ±(99.9%) 0.144 us/op
[info] Iteration   7: 4.187 ±(99.9%) 0.155 us/op
[info] Iteration   8: 4.192 ±(99.9%) 0.386 us/op
[info] Iteration   9: 4.280 ±(99.9%) 0.369 us/op
[info] Iteration  10: 4.201 ±(99.9%) 0.267 us/op
[info] # Run progress: 75.00% complete, ETA 00:02:10
[info] # Fork: 2 of 2
[info] # Warmup Iteration   1: 4.593 ±(99.9%) 0.942 us/op
[info] # Warmup Iteration   2: 4.392 ±(99.9%) 0.511 us/op
[info] # Warmup Iteration   3: 4.233 ±(99.9%) 0.559 us/op
[info] Iteration   1: 4.328 ±(99.9%) 0.505 us/op
[info] Iteration   2: 4.229 ±(99.9%) 0.450 us/op
[info] Iteration   3: 4.233 ±(99.9%) 0.531 us/op
[info] Iteration   4: 4.472 ±(99.9%) 0.417 us/op
[info] Iteration   5: 4.290 ±(99.9%) 0.687 us/op
[info] Iteration   6: 4.229 ±(99.9%) 0.213 us/op
[info] Iteration   7: 4.243 ±(99.9%) 0.209 us/op
[info] Iteration   8: 4.259 ±(99.9%) 0.660 us/op
[info] Iteration   9: 4.356 ±(99.9%) 0.354 us/op
[info] Iteration  10: 4.452 ±(99.9%) 0.305 us/op
[info] Result "com.snowplowanalytics.snowplow.analytics.scalasdk.benchmark.BenchmarkAnalyticsSDK.ordered":
[info]   4.271 ±(99.9%) 0.073 us/op [Average]
[info]   (min, avg, max) = (4.184, 4.271, 4.472), stdev = 0.085
[info]   CI (99.9%): [4.198, 4.345] (assumes normal distribution)
[info] # Run complete. Total time: 00:08:42
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark                       Mode  Cnt  Score   Error   Units
[info] BenchmarkAnalyticsSDK.ordered  thrpt   20  0.728 ± 0.026  ops/us
[info] BenchmarkAnalyticsSDK.ordered   avgt   20  4.271 ± 0.073   us/op

@benjben
Copy link
Contributor

benjben commented Oct 14, 2020

Even better than a 1000x improvement !

@benjben
Copy link
Contributor

benjben commented Oct 14, 2020

With

def ordered: List[(String, Option[Json])] =
    this.asJsonObject.toIterable.map { case (k, v) => (k, Some(v))}.toList

we have

[info]   27.385 ±(99.9%) 3.354 us/op [Average]
[info]   (min, avg, max) = (21.310, 27.385, 31.401), stdev = 3.863
[info]   CI (99.9%): [24.031, 30.739] (assumes normal distribution

A bit slower so will stick to the existing one

@chuwy
Copy link
Contributor Author

chuwy commented Oct 14, 2020

My idea was more to introduce another/replace later the function as Option[Json] is useless an in fact always Json.Null. Without Some(x) and toList I think it will be slightly faster, but it just doesn't matter much and probably a part of the other ticket (but worth to leave the benchmark itself!)

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

No branches or pull requests

2 participants