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

Value Class Option minimal implementation [Arrow 2] #2951

Closed
wants to merge 1 commit into from

Conversation

kyay10
Copy link
Collaborator

@kyay10 kyay10 commented Feb 27, 2023

See #2950 for the more intrusive version of this PR. This implementation just turns Option into a value class, thus removing the Some and None classes, and replacing them with apt fun Some and val None. Note that this change also breaks pattern matching with when on Options, and thus fold needs to be used in a lot of cases (or other apt functions like flatMap, getOrElse, etc)
I reran the benchmarks mentioned in #2950. The code for the benchmarks, and the results for this run, is available on value-option-minimal-benchmark. Here's a summary of the results, benchmarked using kotlinx.benchmark:

data class Option:
Benchmark                                          (iterations)   Mode  Cnt      Score      Error  Units
OptionBenchmark.nestedOptions                              1000  thrpt    5  98433.202 ± 1399.425  ops/s
OptionBenchmark.nestedOptions                             10000  thrpt    5   9718.521 ±   81.801  ops/s
OptionBenchmark.nestedOptions                            100000  thrpt    5    979.794 ±   11.576  ops/s
OptionBenchmark.nestedOptionsBoxed                         1000  thrpt    5  39150.432 ±  449.265  ops/s
OptionBenchmark.nestedOptionsBoxed                        10000  thrpt    5   3670.829 ±  152.522  ops/s
OptionBenchmark.nestedOptionsBoxed                       100000  thrpt    5    420.669 ±    2.569  ops/s
OptionBenchmark.noneComprehension                          1000  thrpt    5  10702.552 ±  263.496  ops/s
OptionBenchmark.noneComprehension                         10000  thrpt    5   1040.239 ±   65.585  ops/s
OptionBenchmark.noneComprehension                        100000  thrpt    5     98.855 ±    6.823  ops/s
OptionBenchmark.noneComprehensionBlocking                  1000  thrpt    5  16987.937 ±   91.261  ops/s
OptionBenchmark.noneComprehensionBlocking                 10000  thrpt    5   1633.712 ±   29.405  ops/s
OptionBenchmark.noneComprehensionBlocking                100000  thrpt    5    157.849 ±    2.479  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking          1000  thrpt    5  26481.168 ±  267.194  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking         10000  thrpt    5   2478.928 ±   30.550  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking        100000  thrpt    5    219.101 ±   10.898  ops/s
OptionBenchmark.noneWithoutComprehension                   1000  thrpt    5  37537.898 ±  369.027  ops/s
OptionBenchmark.noneWithoutComprehension                  10000  thrpt    5   3385.911 ±  113.934  ops/s
OptionBenchmark.noneWithoutComprehension                 100000  thrpt    5    274.607 ±    4.840  ops/s
OptionBenchmark.someComprehension                          1000  thrpt    5   9868.482 ±   48.678  ops/s
OptionBenchmark.someComprehension                         10000  thrpt    5    962.307 ±   17.699  ops/s
OptionBenchmark.someComprehension                        100000  thrpt    5     91.434 ±    0.553  ops/s
OptionBenchmark.someComprehensionBlocking                  1000  thrpt    5  23523.068 ±  358.380  ops/s
OptionBenchmark.someComprehensionBlocking                 10000  thrpt    5   2237.789 ±   79.471  ops/s
OptionBenchmark.someComprehensionBlocking                100000  thrpt    5    205.467 ±   11.091  ops/s
OptionBenchmark.someSingleComprehensionBlocking            1000  thrpt    5  35074.785 ± 3455.037  ops/s
OptionBenchmark.someSingleComprehensionBlocking           10000  thrpt    5   3218.085 ±  131.895  ops/s
OptionBenchmark.someSingleComprehensionBlocking          100000  thrpt    5    290.177 ±    5.021  ops/s
OptionBenchmark.someWithoutComprehension                   1000  thrpt    5  37801.829 ±  427.649  ops/s
OptionBenchmark.someWithoutComprehension                  10000  thrpt    5   3232.409 ±   83.256  ops/s
OptionBenchmark.someWithoutComprehension                 100000  thrpt    5    272.624 ±    3.810  ops/s
value class Option:
Benchmark                                          (iterations)   Mode  Cnt       Score      Error  Units
OptionBenchmark.nestedOptions                              1000  thrpt    5  124709.592 ± 1791.539  ops/s
OptionBenchmark.nestedOptions                             10000  thrpt    5   10926.333 ±   85.847  ops/s
OptionBenchmark.nestedOptions                            100000  thrpt    5    1177.352 ±   72.822  ops/s
OptionBenchmark.nestedOptionsBoxed                         1000  thrpt    5   40915.010 ±  307.201  ops/s
OptionBenchmark.nestedOptionsBoxed                        10000  thrpt    5    4472.095 ±  104.654  ops/s
OptionBenchmark.nestedOptionsBoxed                       100000  thrpt    5     458.587 ±    3.822  ops/s
OptionBenchmark.noneComprehension                          1000  thrpt    5   10162.239 ±   67.199  ops/s
OptionBenchmark.noneComprehension                         10000  thrpt    5     991.392 ±   16.831  ops/s
OptionBenchmark.noneComprehension                        100000  thrpt    5      96.218 ±    0.455  ops/s
OptionBenchmark.noneComprehensionBlocking                  1000  thrpt    5   16740.141 ±   51.344  ops/s
OptionBenchmark.noneComprehensionBlocking                 10000  thrpt    5    1595.652 ±   30.093  ops/s
OptionBenchmark.noneComprehensionBlocking                100000  thrpt    5     152.864 ±    1.810  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking          1000  thrpt    5   26529.191 ±  457.362  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking         10000  thrpt    5    2463.756 ±   22.559  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking        100000  thrpt    5     220.795 ±    2.269  ops/s
OptionBenchmark.noneWithoutComprehension                   1000  thrpt    5   37089.715 ±  772.802  ops/s
OptionBenchmark.noneWithoutComprehension                  10000  thrpt    5    3246.766 ±   17.881  ops/s
OptionBenchmark.noneWithoutComprehension                 100000  thrpt    5     274.617 ±    3.333  ops/s
OptionBenchmark.someComprehension                          1000  thrpt    5    9588.126 ±   71.535  ops/s
OptionBenchmark.someComprehension                         10000  thrpt    5     936.711 ±    3.355  ops/s
OptionBenchmark.someComprehension                        100000  thrpt    5      88.924 ±    0.517  ops/s
OptionBenchmark.someComprehensionBlocking                  1000  thrpt    5   24342.826 ±  233.901  ops/s
OptionBenchmark.someComprehensionBlocking                 10000  thrpt    5    2307.050 ±   18.475  ops/s
OptionBenchmark.someComprehensionBlocking                100000  thrpt    5     213.083 ±    1.277  ops/s
OptionBenchmark.someSingleComprehensionBlocking            1000  thrpt    5   36161.686 ±  957.657  ops/s
OptionBenchmark.someSingleComprehensionBlocking           10000  thrpt    5    3330.991 ±   53.827  ops/s
OptionBenchmark.someSingleComprehensionBlocking          100000  thrpt    5     300.750 ±    2.561  ops/s
OptionBenchmark.someWithoutComprehension                   1000  thrpt    5   37109.414 ±  730.450  ops/s
OptionBenchmark.someWithoutComprehension                  10000  thrpt    5    3390.464 ±   35.098  ops/s
OptionBenchmark.someWithoutComprehension                 100000  thrpt    5     280.734 ±    3.359  ops/s
value class Option minimal:
Benchmark                                          (iterations)   Mode  Cnt      Score      Error  Units
OptionBenchmark.nestedOptions                              1000  thrpt    5  97631.082 ± 5277.028  ops/s
OptionBenchmark.nestedOptions                             10000  thrpt    5   9171.928 ±  404.746  ops/s
OptionBenchmark.nestedOptions                            100000  thrpt    5    954.754 ±   21.827  ops/s
OptionBenchmark.nestedOptionsBoxed                         1000  thrpt    5  40728.082 ±  255.613  ops/s
OptionBenchmark.nestedOptionsBoxed                        10000  thrpt    5   3818.010 ±   27.624  ops/s
OptionBenchmark.nestedOptionsBoxed                       100000  thrpt    5    414.316 ±    3.542  ops/s
OptionBenchmark.noneComprehension                          1000  thrpt    5  10501.040 ±  173.288  ops/s
OptionBenchmark.noneComprehension                         10000  thrpt    5   1027.473 ±    5.143  ops/s
OptionBenchmark.noneComprehension                        100000  thrpt    5     99.263 ±    1.252  ops/s
OptionBenchmark.noneComprehensionBlocking                  1000  thrpt    5  16651.600 ±  171.599  ops/s
OptionBenchmark.noneComprehensionBlocking                 10000  thrpt    5   1596.458 ±   39.806  ops/s
OptionBenchmark.noneComprehensionBlocking                100000  thrpt    5    154.014 ±    2.498  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking          1000  thrpt    5  26705.164 ±  639.156  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking         10000  thrpt    5   2519.346 ±   13.192  ops/s
OptionBenchmark.noneTryCatchComprehensionBlocking        100000  thrpt    5    221.816 ±    1.655  ops/s
OptionBenchmark.noneWithoutComprehension                   1000  thrpt    5  34843.604 ±  429.585  ops/s
OptionBenchmark.noneWithoutComprehension                  10000  thrpt    5   3256.746 ±   32.063  ops/s
OptionBenchmark.noneWithoutComprehension                 100000  thrpt    5    271.060 ±   20.573  ops/s
OptionBenchmark.someComprehension                          1000  thrpt    5   9691.760 ±  152.536  ops/s
OptionBenchmark.someComprehension                         10000  thrpt    5    950.951 ±   11.690  ops/s
OptionBenchmark.someComprehension                        100000  thrpt    5     90.142 ±    0.702  ops/s
OptionBenchmark.someComprehensionBlocking                  1000  thrpt    5  23367.788 ±  290.794  ops/s
OptionBenchmark.someComprehensionBlocking                 10000  thrpt    5   2230.011 ±   13.715  ops/s
OptionBenchmark.someComprehensionBlocking                100000  thrpt    5    205.671 ±    0.763  ops/s
OptionBenchmark.someSingleComprehensionBlocking            1000  thrpt    5  38395.292 ± 2644.370  ops/s
OptionBenchmark.someSingleComprehensionBlocking           10000  thrpt    5   3322.088 ±   27.323  ops/s
OptionBenchmark.someSingleComprehensionBlocking          100000  thrpt    5    297.793 ±    4.198  ops/s
OptionBenchmark.someWithoutComprehension                   1000  thrpt    5  37300.572 ±  744.226  ops/s
OptionBenchmark.someWithoutComprehension                  10000  thrpt    5   3660.777 ±   32.767  ops/s
OptionBenchmark.someWithoutComprehension                 100000  thrpt    5    296.033 ±    5.029  ops/s

Note that this impl is "value class Option minimal, while the more-intrusive #2950 is "value class Option". Seems like the performance impact of this implementation is quite marginal. Not sure if this PR is worth the loss of elegance of when`. Seems like the JVM is very good at optimising tight loops where objects are created and destroyed in there. Maybe the benchmarks are flawed? I'd love to hear thoughts about this!

@kyay10 kyay10 closed this Mar 2, 2023
@kyay10
Copy link
Collaborator Author

kyay10 commented Mar 2, 2023

Closed alongside #2950 in favour of waiting until sealed inline classes become a language feature.

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.

1 participant