Skip to content

Instantly share code, notes, and snippets.

@plokhotnyuk
Created September 27, 2022 06:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save plokhotnyuk/42af1ebfeac791bb5b52bbaeb974acbe to your computer and use it in GitHub Desktop.
Save plokhotnyuk/42af1ebfeac791bb5b52bbaeb974acbe to your computer and use it in GitHub Desktop.

Scalability of JVM processes is limited by GC rate.

For contemporary CPUs and GCs that provide the best throughput the allocation limit is ~11Gb/sec.

After reaching the allocation limit the JVM process doesn't scale.

Having 7.5Gb/sec in 1 thread the limit will be reached at 2-4 threads and adding more threads only decrease the total troughput.

Steps to reproduce that by running JSON parsing benchmarks on your JDK:

  1. Install latest version of sbt and/or ensure that it already installed properly:
sbt about
  1. Clone jsoniter-scala repo:
git clone --depth 1 https://github.com/plokhotnyuk/jsoniter-scala.git
  1. Enter to the cloned directory:
cd jsoniter-scala
  1. Run benchmarks replacing <n> by 1, 2, 4, 8, and 16 (the number of parsing threads):
sbt 'jsoniter-scala-benchmarkJVM/jmh:run -t <n> -prof gc -p size=128 ArrayOfCharsReading.(zioJson|jsoniterScala)'

Below are results of benchmarks that parse JSON array of 1-char JSON strings to Array[Char] using using zio-json and jsoniter-scala.

The parallel GC is used with ParallelGCThreads = 13 (default on the tested environmant), to set explicitly use -XX:ParallelGCThreads=<n>, where <n> should be replaced by a number of GC threads.

Environment: Intel® Core™ i9-11900H CPU @ 2.5GHz (max 4.9GHz), RAM 32Gb DDR4-3200, Ubuntu 22.04, and latest versions of Azul Zulu 1

1 thread

[info] Benchmark                                                           (size)   Mode  Cnt        Score       Error   Units
[info] ArrayOfCharsReading.jsoniterScala                                      128  thrpt    5  1803944.618 ± 41321.739   ops/s
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate                       128  thrpt    5      623.582 ±    14.049  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate.norm                  128  thrpt    5      544.018 ±     0.025    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space              128  thrpt    5      613.826 ±   879.374  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space.norm         128  thrpt    5      535.326 ±   763.468    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space          128  thrpt    5        0.013 ±     0.050  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space.norm     128  thrpt    5        0.012 ±     0.044    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.count                            128  thrpt    5        6.000              counts
[info] ArrayOfCharsReading.jsoniterScala:·gc.time                             128  thrpt    5        8.000                  ms
[info] ArrayOfCharsReading.zioJson                                            128  thrpt    5   367381.109 ±  9385.923   ops/s
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate                             128  thrpt    5     7453.477 ±   191.421  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate.norm                        128  thrpt    5    31920.995 ±     0.160    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space                    128  thrpt    5     7471.190 ±  1080.227  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space.norm               128  thrpt    5    31995.178 ±  4337.185    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space                128  thrpt    5        0.329 ±     0.208  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space.norm           128  thrpt    5        1.409 ±     0.896    B/op
[info] ArrayOfCharsReading.zioJson:·gc.count                                  128  thrpt    5       73.000              counts
[info] ArrayOfCharsReading.zioJson:·gc.time                                   128  thrpt    5       40.000                  ms

2 threads

[info] Benchmark                                                           (size)   Mode  Cnt        Score       Error   Units
[info] ArrayOfCharsReading.jsoniterScala                                      128  thrpt    5  3262574.427 ± 64212.694   ops/s
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate                       128  thrpt    5     1127.925 ±    22.327  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate.norm                  128  thrpt    5      544.021 ±     0.018    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space              128  thrpt    5     1125.598 ±   880.921  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space.norm         128  thrpt    5      542.912 ±   425.070    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space          128  thrpt    5        0.846 ±     7.024  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space.norm     128  thrpt    5        0.410 ±     3.408    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.count                            128  thrpt    5       11.000              counts
[info] ArrayOfCharsReading.jsoniterScala:·gc.time                             128  thrpt    5       10.000                  ms
[info] ArrayOfCharsReading.zioJson                                            128  thrpt    5   514184.868 ±  4543.376   ops/s
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate                             128  thrpt    5    10422.398 ±    91.917  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate.norm                        128  thrpt    5    31896.977 ±     0.064    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space                    128  thrpt    5    10437.287 ±  1080.341  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space.norm               128  thrpt    5    31943.709 ±  3499.154    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space                128  thrpt    5        0.400 ±     0.291  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space.norm           128  thrpt    5        1.223 ±     0.885    B/op
[info] ArrayOfCharsReading.zioJson:·gc.count                                  128  thrpt    5      102.000              counts
[info] ArrayOfCharsReading.zioJson:·gc.time                                   128  thrpt    5       46.000                  ms

4 threads

[info] Benchmark                                                           (size)   Mode  Cnt        Score         Error   Units
[info] ArrayOfCharsReading.jsoniterScala                                      128  thrpt    5  6293147.286 ± 1191058.026   ops/s
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate                       128  thrpt    5     2175.291 ±     412.018  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate.norm                  128  thrpt    5      544.019 ±       0.008    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space              128  thrpt    5     2250.919 ±    1079.229  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space.norm         128  thrpt    5      563.004 ±     248.343    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space          128  thrpt    5        0.042 ±       0.057  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space.norm     128  thrpt    5        0.010 ±       0.013    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.count                            128  thrpt    5       22.000                counts
[info] ArrayOfCharsReading.jsoniterScala:·gc.time                             128  thrpt    5        9.000                    ms
[info] ArrayOfCharsReading.zioJson                                            128  thrpt    5   535169.029 ±    6592.923   ops/s
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate                             128  thrpt    5    10846.887 ±     132.774  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate.norm                        128  thrpt    5    31896.972 ±       0.104    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space                    128  thrpt    5    10947.448 ±    1083.443  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space.norm               128  thrpt    5    32194.627 ±    3511.139    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space                128  thrpt    5        0.495 ±       0.280  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space.norm           128  thrpt    5        1.457 ±       0.840    B/op
[info] ArrayOfCharsReading.zioJson:·gc.count                                  128  thrpt    5      107.000                counts
[info] ArrayOfCharsReading.zioJson:·gc.time                                   128  thrpt    5       40.000                    ms

8 threads

[info] Benchmark                                                           (size)   Mode  Cnt         Score        Error   Units
[info] ArrayOfCharsReading.jsoniterScala                                      128  thrpt    5  10900561.711 ± 661598.038   ops/s
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate                       128  thrpt    5      3766.625 ±    229.334  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate.norm                  128  thrpt    5       544.018 ±      0.005    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space              128  thrpt    5      3784.244 ±   1080.053  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space.norm         128  thrpt    5       546.501 ±    148.032    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space          128  thrpt    5         0.075 ±      0.166  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space.norm     128  thrpt    5         0.011 ±      0.023    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.count                            128  thrpt    5        37.000               counts
[info] ArrayOfCharsReading.jsoniterScala:·gc.time                             128  thrpt    5        12.000                   ms
[info] ArrayOfCharsReading.zioJson                                            128  thrpt    5    496724.659 ±  13676.717   ops/s
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate                             128  thrpt    5     10066.491 ±    280.478  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate.norm                        128  thrpt    5     31896.985 ±      0.057    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space                    128  thrpt    5     10123.091 ±    880.887  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space.norm               128  thrpt    5     32074.971 ±   2336.857    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space                128  thrpt    5         0.379 ±      0.280  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space.norm           128  thrpt    5         1.199 ±      0.873    B/op
[info] ArrayOfCharsReading.zioJson:·gc.count                                  128  thrpt    5        99.000               counts
[info] ArrayOfCharsReading.zioJson:·gc.time                                   128  thrpt    5        32.000                   ms

16 threads

[info] Benchmark                                                           (size)   Mode  Cnt         Score       Error   Units
[info] ArrayOfCharsReading.jsoniterScala                                      128  thrpt    5  11230335.635 ± 44550.991   ops/s
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate                       128  thrpt    5      3881.520 ±    18.729  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.alloc.rate.norm                  128  thrpt    5       544.019 ±     0.005    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space              128  thrpt    5      3873.084 ±  1101.210  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Eden_Space.norm         128  thrpt    5       542.841 ±   154.625    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space          128  thrpt    5         0.100 ±     0.222  MB/sec
[info] ArrayOfCharsReading.jsoniterScala:·gc.churn.PS_Survivor_Space.norm     128  thrpt    5         0.014 ±     0.031    B/op
[info] ArrayOfCharsReading.jsoniterScala:·gc.count                            128  thrpt    5        38.000              counts
[info] ArrayOfCharsReading.jsoniterScala:·gc.time                             128  thrpt    5         9.000                  ms
[info] ArrayOfCharsReading.zioJson                                            128  thrpt    5    464041.176 ±  1826.740   ops/s
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate                             128  thrpt    5      9421.986 ±    72.543  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.alloc.rate.norm                        128  thrpt    5     31897.095 ±     0.531    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space                    128  thrpt    5      9568.482 ±   821.021  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Eden_Space.norm               128  thrpt    5     32392.991 ±  2760.087    B/op
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space                128  thrpt    5         0.124 ±     0.224  MB/sec
[info] ArrayOfCharsReading.zioJson:·gc.churn.PS_Survivor_Space.norm           128  thrpt    5         0.420 ±     0.758    B/op
[info] ArrayOfCharsReading.zioJson:·gc.count                                  128  thrpt    5        94.000              counts
[info] ArrayOfCharsReading.zioJson:·gc.time                                   128  thrpt    5        22.000                  ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment