[infinispan-dev] Avoid Collections.emptySet() / emptyMap() / emptyList

Galder Zamarreño galder at redhat.com
Tue Oct 23 08:39:34 EDT 2012


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

>  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




More information about the infinispan-dev mailing list