Parcelable vs Serializable

来源:互联网 发布:扎克拉文体测数据 编辑:程序博客网 时间:2024/06/15 01:33

转自:http://www.developerphil.com/parcelable-vs-serializable/

When starting on Android, we all learn that we cannot just pass object references to activities and fragments, we have to put those in an Intent / Bundle.

Looking at the api, we realize that we have two options, we can either make our objectsParcelable orSerializable. As Java developers, we already know of the Serializable mechanism, so why bother with Parcelable?

To answer this, lets take a look at both approaches.

Serializable, the Master of Simplicity

// access modifiers, accessors and constructors omitted for brevitypublic class SerializableDeveloper implements Serializable    String name;    int yearsOfExperience;    List<Skill> skillSet;    float favoriteFloat;      static class Skill implements Serializable {        String name;        boolean programmingRelated;    }}

The beauty of serializable is that you only need to implement the Serializable interface on a class and its children. It is a marker interface, meaning that there is no method to implement, Java will simply do its best effort to serialize it efficiently.

The problem with this approach is that reflection is used and it is a slow process. This mechanism also tends to create a lot of temporary objects and cause quite a bit of garbage collection.

Parcelable, the Speed King

// access modifiers, accessors and regular constructors ommited for brevityclass ParcelableDeveloper implements Parcelable {    String name;    int yearsOfExperience;    List<Skill> skillSet;    float favoriteFloat;      ParcelableDeveloper(Parcel in) {        this.name = in.readString();        this.yearsOfExperience = in.readInt();        this.skillSet = new ArrayList<Skill>();        in.readTypedList(skillSet, Skill.CREATOR);        this.favoriteFloat = in.readFloat();    }      void writeToParcel(Parcel dest, int flags) {        dest.writeString(name);        dest.writeInt(yearsOfExperience);        dest.writeTypedList(skillSet);        dest.writeFloat(favoriteFloat);    }      int describeContents() {        return 0;    }        static final Parcelable.Creator<ParcelableDeveloper> CREATOR            = new Parcelable.Creator<ParcelableDeveloper>() {          ParcelableDeveloper createFromParcel(Parcel in) {            return new ParcelableDeveloper(in);        }          ParcelableDeveloper[] newArray(int size) {            return new ParcelableDeveloper[size];        }    };      static class Skill implements Parcelable {        String name;        boolean programmingRelated;          Skill(Parcel in) {            this.name = in.readString();            this.programmingRelated = (in.readInt() == 1);        }          @Override        void writeToParcel(Parcel dest, int flags) {            dest.writeString(name);            dest.writeInt(programmingRelated ? 1 : 0);        }          static final Parcelable.Creator<Skill> CREATOR             = new Parcelable.Creator<Skill>() {              Skill createFromParcel(Parcel in) {                return new Skill(in);            }              Skill[] newArray(int size) {                return new Skill[size];            }        };          @Override        int describeContents() {            return 0;        }    }}
According togoogle engineers, this code will run significantly faster. One of the reasons for this is that we are being explicit about the serialization process instead of using reflection to infer it. It also stands to reason that the code has been heavily optimized for this purpose.

However, it is obvious here that implementing Parcelable is not free. There is a significant amount of boilerplate code and it makes the classes harder to read and maintain.

Speed Tests

Of course, we want to know how much faster Parcelable is.

The methodology

  • Mimic the process of passing object to an activity by putting an object in a bundle and callingBundle#writeToParcel(Parcel, int) and then fetching it back
  • Run this in a loop 1000 times
  • Do an average on 10 separate runs to account for memory allocation, other apps using the cpu, etc
  • The object under test are the SerializableDeveloper and the ParcelableDeveloper shown above
  • Test on multiple devices – android versions
    • LG Nexus 4 – Android 4.2.2 
    • Samsung Nexus 10 – Android 4.2.2
    • HTC Desire Z – Android 2.3.3

The results

parcelable vs serializable

Nexus 10

Serializable: 1.0004ms,  Parcelable: 0.0850ms – 10.16x improvement.

Nexus 4

Serializable: 1.8539ms – Parcelable: 0.1824ms – 11.80x improvement.

Desire Z

Serializable: 5.1224ms – Parcelable: 0.2938ms – 17.36x improvement.

There you have it: Parcelable is more than 10x faster than Serializable! It is also interesting to note that even on a Nexus 10, a pretty simple object can take about 1 millisecond to go through a full serialize/deserialize cycle.

The Bottom Line

If you want to be a good citizen, take the extra time to implement Parcelable since it will perform 10 times faster and use less resources.

However, in most cases, the slowness of Serializable won’t be noticeable. Feel free to use it  but  remember that serialization is an expensive operation so keep it to a minimum.

If you are trying to pass a list with thousands of serialized objects, it is possible that the whole process will take more than a second. It can make transitions or rotation from portrait to lanscape feel very sluggish.


Benefit of using Parcelable instead of serializing object

Question:

As I understand, Bundle and Parcelable belongs to the way Android performs serialization in. It is used for example in passing data between activities. But I wonder, if there are any benefits in usingParcelable instead of classic serialization in case of saving state of my business objects to the internal memory for example? Will it be simpler or faster than the classic way? Where should I use classic serialization and where better to use bundles?

Answer:

From "Pro Android 2"

NOTE: Seeing Parcelable might have triggered the question, why is Android not using the built-in Java serialization mechanism? It turns out that the Android team came to the conclusion that the serialization in Java is far too slow to satisfy Android’s interprocess-communication requirements. So the team built the Parcelable solution. The Parcelable approach requires that you explicitly serialize the members of your class, but in the end, you get a much faster serialization of your objects.

Also realize that Android provides two mechanisms that allow you to pass data to another process. The first is to pass a bundle to an activity using an intent, and the second is to pass a Parcelable to a service. These two mechanisms are not interchangeable and should not be confused. That is, the Parcelable is not meant to be passed to an activity. If you want to start an activity and pass it some data, use a bundle. Parcelable is meant to be used only as part of an AIDL definition.


0 0
原创粉丝点击