[infinispan-dev] Avoid Collections.emptySet() / emptyMap() / emptyList
David M. Lloyd
david.lloyd at redhat.com
Tue Oct 23 09:55:28 EDT 2012
On 10/23/2012 07:39 AM, Galder Zamarreño wrote:
>
> On Oct 22, 2012, at 3:40 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>
>> On 10/22/2012 01:41 AM, Galder Zamarreño wrote:
>>>
>>> On Oct 19, 2012, at 7:20 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>>>
>>>> Also be aware that JBMAR has specific optimizations for the JDK empty
>>>> collections - they are represented by a single byte in the stream.
>>>
>>> Well, it's actually 3 bytes that you use to represent empty collections (at least in 1.3.15ga):
>>>
>>> write(ID_NEW_OBJECT);
>>> write(ID_CLASS_CLASS);
>>> write(classByte);
>>>
>>> Whereas with our externalizers, these get resolved via object writer (which gets called before your code to detect empty collections) and it only writes 1 byte:
>>>
>>> write(externalizerId);
>>
>> No, that's inaccurate; they are singletons and do not use ID_NEW_OBJECT.
>
> Really?
>
> https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L169
That code is the code path that is executed if you write, for example.
Collections.emptySet().getClass(). The code you're interested in is:
https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L713
>
>> They're done as instances so it is one of:
>>
>> public static final int ID_EMPTY_LIST_OBJECT = 0x5d;
>> public static final int ID_EMPTY_SET_OBJECT = 0x62;
>> public static final int ID_EMPTY_MAP_OBJECT = 0x69;
>>
>> Your externalizers on the other hand take multiple bytes even in the
>> simplest case. If it is that important, you could use an ObjectResolver
>> to swap in the JDK instance instead of using yet another externalizer
>> (which has several bytes of overhead of its own).
>
> Well, to be completely precise, our version will write two bytes:
>
> 1st byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L140
> 2nd byte: https://github.com/galderz/infinispan/blob/t_memory/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerTable.java#L397
>
> I still see 3 bytes written in your case:
>
> 1st byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L169
> 2nd byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L1133
> 3rd byte: class byte, as indicated in https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L167
>
> Not sure if you remember but we have ObjectTable.Writer in what we call ExternalizerTable, which given a type, it resolves into an Infinispan Externalizer.
>
> Now, given Collections.Empty<Set>, it will resolve to an adapter that writes the ID of the externalizer (in this case InfinsipanCollections.EmptySet.Externalizer), and then will delegate to its writeObject, which does nothing.
>
>>
>> --
>> - DML
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>
>
> --
> Galder Zamarreño
> galder at redhat.com
> twitter.com/galderz
>
> Project Lead, Escalante
> http://escalante.io
>
> Engineer, Infinispan
> http://infinispan.org
>
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>
--
- DML
More information about the infinispan-dev
mailing list