This is pretty interesting. I think that you're right in your assessment
that these changes would adversely affect performance, but I don't agree
that the performance changes are unimportant on the client. In my
experience, using Java Reflection for anything that is vaguely
performance-critical gets you in a lot of trouble. All the generated
metadata stuff is designed with this in mind.

I'm a bit surprised that you got that degree of size reduction from your
changes. I would be open to incorporating some of them - the toString helper
method, for instance - and perhaps adding switches for things like equals
and compareTo, if it's reasonable to remove them at times. I don't think it
makes sense to branch the serialization code, though.

One question I have in general, though, is why does the size of the jar
matter at all? It's not like it's going to take up tons of memory or slow
you down particularly when being transferred around.

-Bryan

On Thu, Jul 22, 2010 at 11:34 AM, Emmanuel Bourg <ebo...@apache.org> wrote:

> Hi all,
>
> I'm new to Thrift and I started playing lately with a generated Java
> client. I was somewhat struck by the size of the resulting jar, about 3MB
> for an interface consisting of about 30 service methods and 150 structs of
> variable size.
>
> The generated classes contain code that isn't always useful, like the
> equals() and compareTo() methods. The implementation of toString() could
> easily be delegated to an utility class. Annotations could be used to
> represent the metadata. The service implementation contains the client and
> the server, but I rarely need both at the same time.
>
> From these observations I tweaked the compiler to generate minimal classes.
> For example a simple struct like this one:
>
>  struct Person {
>    1:i32 id,
>    2:string name,
>    3:string email
>  }
>
> will translate into the following class:
>
>  @ThriftStruct("Person")
>  public class Person implements Serializable {
>
>    @ThriftField(name="id", type=TType.I32, id=1)
>    public int id;
>
>    @ThriftField(name="name", type=TType.STRING, id=2)
>    public String name;
>
>    @ThriftField(name="email", type=TType.STRING, id=3)
>    public String email;
>
>    public int getId() {
>      return this.id;
>    }
>
>    public void setId(int id) {
>      this.id = id;
>    }
>
>    public String getName() {
>      return this.name;
>    }
>
>    public void setName(String name) {
>      this.name = name;
>    }
>
>    public String getEmail() {
>      return this.email;
>    }
>
>    public void setEmail(String email) {
>      this.email = email;
>    }
>
>    public String toString() {
>      return ToStringBuilder.toString(this);
>    }
>  }
>
> The read() and write() methods are now implemented in a utility class using
> reflection to find out the fields being serialized. That's probably slower
> than the static code generated by the original compiler but that's less
> critical on the client side.
>
> With these modifications the resulting jar was about 10 times smaller in my
> case.
>
> I uploaded the code on Github if someone is interested to look into it.
> It's derived from the 0.2 branch.
>
> http://github.com/ebourg/thrift
> http://wiki.github.com/ebourg/thrift
>
>
> Emmanuel Bourg
>
>

Reply via email to