<div dir="ltr">Hi Sebastien,<div><br></div><div>First thing to say, you impress me with all this work ! Thank you very much !</div><div><br></div><div>I&#39;ve been working with Scala for almost three years, and I really appreciate the functional code style. This involves the use of Optionals among other things you mention like map, flapMap etc. Looking at the performance test, it seems Optionals are not an issue, so it&#39;s more a matter of coding style and design in most of the cases.</div><div>After my experience with scala, I believe that if Optional do indeed avoid NullpointerException, they introduce NoSuchElemenException. Because the coding style with functional programming is more than a matter of Optionals Yes or No. It&#39;s very different from imperative programming and this will be hard to do really &quot;as it should&quot; in infinispan code base. So in the end, there will be moments where we will be calling &quot;get&quot; to an empty Optional, leading to the kind of bugs you listed before involving NullPointerException. At least, this is the case in my experience, specially coming from years of Java coding and with such a huge code base. </div><div>But I think it&#39;s good to use Optionals, specially on return types (not in method parameters). </div><div><br></div><div>So 1+ to use Optionals, and  +1 to decide clearly how and when and following which coding style rules we should introduce them in our public APIs, internal APIs and codebase in general.<br></div><div><br></div><div>My 2 cents,</div><div><br></div><div>Katia</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 18, 2017 at 1:30 PM, Sebastian Laskawiec <span dir="ltr">&lt;<a href="mailto:slaskawi@redhat.com" target="_blank">slaskawi@redhat.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hey!<div><br></div><div>In our past we had a couple of discussions about whether we should or should not use Optionals [1][2]. The main argument against it was performance. </div><div><br></div><div>On one hand we risk additional object allocation (the Optional itself) and wrong inlining decisions taken by C2 compiler [3]. On the other hand we all probably &quot;feel&quot; that both of those things shouldn&#39;t be a problem and should be optimized by C2. Another argument was the Optional&#39;s doesn&#39;t give us anything but as I checked, we introduced nearly 80 NullPointerException bugs in two years [4]. So we might consider Optional as a way of fighting those things. The final argument that I&#39;ve seen was about lack of higher order functions which is simply not true since we have #map, #filter and #flatmap functions. You can do pretty amazing things with this.</div><div><br></div><div>I decided to check the performance when refactoring REST interface. I created a PR with Optionals [5], ran performance tests, removed all Optionals and reran tests. You will be surprised by the results [6]:</div><div><br></div><div><table cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:13px;font-family:arial,sans,sans-serif;border-collapse:collapse;border:none"><colgroup><col width="192"><col width="100"><col width="100"><col width="100"><col width="100"><col width="100"><col width="100"><col width="100"></colgroup><tbody><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-width:1px;border-style:solid;border-color:rgb(0,0,0);text-align:center" rowspan="2" colspan="2"><div style="max-height:41px">Test case</div></td><td style="padding:2px 3px;vertical-align:bottom;border-top:1px solid rgb(0,0,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:center" rowspan="1" colspan="3">With Optionals [%]</td><td style="padding:2px 3px;vertical-align:bottom;border-top:1px solid rgb(0,0,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:center" rowspan="1" colspan="3">Without Optionals</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-decoration-line:underline;color:rgb(17,85,204);text-align:center"><a class="m_-460102615607407004inbox-inbox-in-cell-link" href="http://perfrepo.mw.lab.eng.bos.redhat.com/reports/tableComparisonReport/5471" target="_blank">Run 1</a></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-decoration-line:underline;color:rgb(17,85,204);text-align:center"><a class="m_-460102615607407004inbox-inbox-in-cell-link" href="http://perfrepo.mw.lab.eng.bos.redhat.com/reports/tableComparisonReport/5474" target="_blank">Run 2</a></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:center">Avg</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-decoration-line:underline;color:rgb(17,85,204);text-align:center"><a class="m_-460102615607407004inbox-inbox-in-cell-link" href="http://perfrepo.mw.lab.eng.bos.redhat.com/reports/tableComparisonReport/5472" target="_blank">Run 1</a></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-decoration-line:underline;color:rgb(17,85,204);text-align:center"><a class="m_-460102615607407004inbox-inbox-in-cell-link" href="http://perfrepo.mw.lab.eng.bos.redhat.com/reports/tableComparisonReport/5475" target="_blank">Run 2</a></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:center">Avg</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);border-left:1px solid rgb(0,0,0)" rowspan="2" colspan="1"><div style="max-height:41px">Non-TX reads 10 threads </div></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Throughput</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">32.54</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">32.87</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">32.71</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">31.74</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">34.04</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">32.89</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Response time</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-24.12</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-24.63</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-24.38</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-24.37</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-25.69</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-25.03</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);border-left:1px solid rgb(0,0,0)" rowspan="2" colspan="1"><div style="max-height:41px">Non-TX reads 100 threads </div></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Throughput</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">6.48</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-12.79</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-3.16</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-7.06</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-6.14</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-6.60</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Response time</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-6.15</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">14.93</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">4.39</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">7.88</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">6.49</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">7.19</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);border-left:1px solid rgb(0,0,0)" rowspan="2" colspan="1"><div style="max-height:41px">Non-TX writes 10 threads </div></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Throughput</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">9.21</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">7.60</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">8.41</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">4.66</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">7.15</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">5.91</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Response time</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-8.92</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-7.11</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-8.02</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-5.29</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-6.93</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-6.11</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);border-left:1px solid rgb(0,0,0)" rowspan="2" colspan="1"><div style="max-height:41px">Non-TX writes 100 threads </div></td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Throughput</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">2.53</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">1.65</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">2.09</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-1.16</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">4.67</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">1.76</td></tr><tr style="height:21px"><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0)">Response time</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-2.13</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-1.79</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-1.96</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">0.91</td><td style="padding:2px 3px;vertical-align:bottom;border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-4.67</td><td style="padding:2px 3px;vertical-align:bottom;background-color:rgb(0,255,0);border-right:1px solid rgb(0,0,0);border-bottom:1px solid rgb(0,0,0);text-align:right">-1.88</td></tr></tbody></table></div><div><br></div><div>I also created JMH + Flight Recorder tests and again, the results showed no evidence of slow down caused by Optionals [7].</div><div><br></div><div>Now please take those results with a grain of salt since they tend to drift by a factor of +/-5% (sometimes even more). <b><u>But it&#39;s very clear the performance results are very similar if not the same.</u></b></div><div><br></div><div>Having those numbers at hand, do we want to have Optionals in Infinispan codebase or not? And if not, let&#39;s state it very clearly (and write it into contributing guide), it&#39;s because we don&#39;t like them. Not because of performance.</div><div><br></div><div>Thanks,</div><div>Sebastian</div><div><br></div><div>[1] <a href="http://lists.jboss.org/pipermail/infinispan-dev/2017-March/017370.html" target="_blank">http://lists.jboss.org/<wbr>pipermail/infinispan-dev/2017-<wbr>March/017370.html</a></div><div>[2] <a href="http://lists.jboss.org/pipermail/infinispan-dev/2016-August/016796.html" target="_blank">http://lists.jboss.org/<wbr>pipermail/infinispan-dev/2016-<wbr>August/016796.html</a></div><div>[3] <a href="http://vanillajava.blogspot.ro/2015/01/java-lambdas-and-low-latency.html" target="_blank">http://vanillajava.<wbr>blogspot.ro/2015/01/java-<wbr>lambdas-and-low-latency.html</a></div><div>[4] <a href="https://issues.jboss.org/issues/?jql=project%20%3D%20ISPN%20AND%20issuetype%20%3D%20Bug%20AND%20text%20%7E%20%22NullPointerException%22%20AND%20created%20%3E%3D%202015-04-27%20AND%20created%20%3C%3D%202017-04-27" target="_blank">https://issues.jboss.org/<wbr>issues/?jql=project%20%3D%<wbr>20ISPN%20AND%20issuetype%20%<wbr>3D%20Bug%20AND%20text%20%7E%<wbr>20%22NullPointerException%22%<wbr>20AND%20created%20%3E%3D%<wbr>202015-04-27%20AND%20created%<wbr>20%3C%3D%202017-04-27</a></div><div>[5] <a href="https://github.com/infinispan/infinispan/pull/5094" target="_blank">https://github.com/<wbr>infinispan/infinispan/pull/<wbr>5094</a></div><div>[6] <a href="https://docs.google.com/a/redhat.com/spreadsheets/d/1oep6Was0FfvHdqBCwpCFIqcPfJZ5-5_YYUqlRtUxEkM/edit?usp=sharing" target="_blank">https://docs.google.com/a/<wbr>redhat.com/spreadsheets/d/<wbr>1oep6Was0FfvHdqBCwpCFIqcPfJZ5-<wbr>5_YYUqlRtUxEkM/edit?usp=<wbr>sharing</a></div><div>[7] <a href="https://github.com/infinispan/infinispan/pull/5094#issuecomment-296970673" target="_blank">https://github.com/<wbr>infinispan/infinispan/pull/<wbr>5094#issuecomment-296970673</a></div></div><span class="HOEnZb"><font color="#888888"><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature"><div dir="ltr"><p class="m_-460102615607407004inbox-inbox-fullname-container" style="box-sizing:border-box;color:rgb(0,0,0);font-family:overpass,sans-serif;font-weight:bold;margin:0px;padding:0px;font-size:14px;text-transform:uppercase"><span class="m_-460102615607407004inbox-inbox-firstname-container" style="box-sizing:border-box">SEBASTIAN</span><span class="m_-460102615607407004inbox-inbox-Apple-converted-space"> </span><span class="m_-460102615607407004inbox-inbox-lastname-container" style="box-sizing:border-box">ŁASKAWIEC</span></p><p class="m_-460102615607407004inbox-inbox-position-container" style="box-sizing:border-box;color:rgb(0,0,0);font-family:overpass,sans-serif;font-size:10px;margin:0px 0px 4px;text-transform:uppercase"><span class="m_-460102615607407004inbox-inbox-position" style="box-sizing:border-box">INFINISPAN DEVELOPER</span></p><p class="m_-460102615607407004inbox-inbox-legal-container" style="box-sizing:border-box;font-family:overpass,sans-serif;margin:0px;font-size:10px;color:rgb(153,153,153)"><a class="m_-460102615607407004inbox-inbox-redhat-anchor" href="https://www.redhat.com/" style="box-sizing:border-box;color:rgb(0,136,206);margin:0px;text-decoration:none" target="_blank">Red Hat<span class="m_-460102615607407004inbox-inbox-Apple-converted-space"> </span><span style="box-sizing:border-box">EMEA</span></a></p><table border="0" style="box-sizing:border-box;color:rgb(0,0,0);font-family:overpass,sans-serif;font-size:medium"><tbody style="box-sizing:border-box"><tr style="box-sizing:border-box"><td width="100px" style="box-sizing:border-box"><a href="https://red.ht/sig" style="box-sizing:border-box" target="_blank"><img width="90" height="auto" style="box-sizing:border-box" src="https://www.redhat.com/files/brand/email/sig-redhat.png"></a></td></tr></tbody></table></div></div>
</font></span><br>______________________________<wbr>_________________<br>
infinispan-dev mailing list<br>
<a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/<wbr>mailman/listinfo/infinispan-<wbr>dev</a><br></blockquote></div><br></div>