hg: lambda/lambda/jdk: - ensure null values are retained
Remi Forax
forax at univ-mlv.fr
Wed Dec 5 00:46:09 PST 2012
On 12/04/2012 02:53 PM, Paul Sandoz wrote:
> On Dec 4, 2012, at 2:26 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>> On 12/04/2012 11:44 AM, Paul Sandoz wrote:
>>> Hi Remi,
>>>
>>> Many thanks, that is just the kind of VM-perspective advice i was looking for. I was assuming that the VM would be able to somehow inline the hot path to the else block.
>> yes, but you don't need a supplementary field for that.
>>
> Right, but subjectively i think it is marginally clearer code.
>
>
>>> So you are suggesting something like this:
>>>
>>> T _t = (T) maskNull(t);
>>> if (lastSeen == null || !lastSeen.equals(_t)) {
>>> lastSeen = _t;
>>> downstream.accept(t);
>>> }
>> I was thinking to something like this:
>>
>> return new Sink.ChainedReference<T>(sink) {
>> private Object lastSeen;
>>
>> @Override
>> public void begin(long size) {
>> lastSeen = null; // not needed if end() is called in a finally ?
> It's not needed.
>
>
>> downstream.begin(-1);
>> }
>>
>> @Override
>> public void end() {
>> lastSeen = null;
>> downstream.end();
>> }
>>
>> @Override
>> public void accept(T t) {
>> if (t == null) {
>> if (lastSeen != NULL_OBJECT) {
>> lastSeen = NULL_OBJECT
>> downstream.accept(null);
>> }
>> } else if (lastSeen == null || !t.equals(lastSeen)) {
>> lastSeen = t;
>> downstream.accept((T)t);
>> }
>> }
>> };
>>
> If one assumes nulls are rare is there any performance advantage (beyond the extra field not being used) to using the null object design pattern in this context?
Not for this code, but remember that I've sent the mail for the whole patch.
I believe that that an holistic approach should be used in all ops,
because all ops need to deal with null.
>
> I am trying and failing to correlate what you say below with the code base:
>
> "Your solution require to load/store value from the RAM because the VM will not able to optimize this code (inlining is often defeated due to the fact that the call between ops is a virtual call)."
I've written this sentence when I've read the last lines of your patch,
the one that use an AtomicInteger because you can't store null in a CHM.
Masking null in that case avoid multiple accesses to the RAM.
>
> Paul.
Rémi
More information about the lambda-dev
mailing list