[Android] Parcelable vs Serializable 우린 뭘 써야할까?

Jay·2021년 3월 17일
2

Android

목록 보기
23/39
post-thumbnail
post-custom-banner

차이를 알고 쓰자.

이 글은 Parcelable vs Serializable , 정말 Serializable은 느릴까?
해당 글을 읽고 작성 되었으며 일부를 참고하고 있습니다.

평소 Object를 Intent를 통해 넘길 때 너무 자연스럽게도 parcelable 키워드를 사용하여 bundle값에 집어 넣어서 Object를 다른 액티비티로 넘겼다.

당연하게 사용하는게 무섭다는 것을 느꼈다.

어디서 들은 이야기로 빠르더라...
그게 더 좋다더라... 는 결국 명확한 뒷받침이 없는 의견이다.

이 글에서 직렬화/역직렬화 과정은 다루지 않겠다.
성능 비교를 위한 글이다.

Serializable

  • Serializable 은 Android SDK 가 아닌 표준 Java 의 인터페이스 입니다.
  • 자바 기본 타입(primitive type)과 java.io.Serializable 인터페이스를 상속 받은 객체는 직렬화를 위한 기본 조건을 충족한다.
 public class Member implements Serializable {
        private String name;
        private String email;
        private int age;
    
        public Member(String name, String email, int age) {
            this.name = name;
            this.email = email;
            this.age = age;
        }
    
        // Getter Setter 생략
    
        @Override
        public String toString() {
            return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
        }
    }
  • Serializable은 해당 클래스가 직렬화 대상이라고 알려주기만 할 뿐 어떠한 메서드도 가지지 않는 단순한 "마커 인터페이스" 이기에 사용자는 매우 쉽게 사용할 수 있다.
  • 내부적으로 Serializable은 reflection을 사용하고 이는 처리 과정 중 많은 추가 객체를 생성함을 의미한다. 생성된 추가 객체들은 GC의 타겟이 되고 GC의 과도한 동작으로 성능 저하 및 배터리 소모로 이어진다. (사실 이게 Parcelizable이 더 좋다고 하는 Serializable의 큰 단점이지 않을까?)

Parcelizable

  • 직렬화를 위한 인터페이스
  • Serializable과 다르게 표준 Java가 아닌 Android SDK의 인터페이스
  • Serializable과 다르게 reflection을 사용하지 않음.
  • IPC(Inter Process Communication)에 최적화된 기능 제공

대신 Serializable에서 간단하게 작성하던 코드보다 훨씬 귀찮게 구현해줘야 하는 필수 메서드들을 포함한다.

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {

    private String firstName;
    private String lastName;
    private int age;


    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }


    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.firstName);
        dest.writeString(this.lastName);
        dest.writeInt(this.age);
    }

    protected Person(Parcel in) {
        this.firstName = in.readString();
        this.lastName = in.readString();
        this.age = in.readInt();
    }

    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}

Serializable이 시스템 비용을 발생시키고 Parcelizable은 구현 및 유지 보수 비용이 든다고 한다.
즉, 뭐가 더 좋다라기보단 뭐가 더 서비스에 부합할까의 문제같다.


🤔 왜 사람들은 Serializable이 Parcelizable보다 느리다고 하는걸까?

serialization은 reflection 방법을 사용하여 serialization을 하는데, parcelable은 프로그래머가 직접 바로 setting 해주기에 빠르다.

둘에 대한 성능차이로 유명한 사진이다.

이미지 출처 : http://www.developerphil.com/parcelable-vs-serializable/

🙌

위와 같은 성능비교는 Serializable이 reflection을 내부로 사용하는 방식에서의 Parcelizable과 비교하기에 비교가 맞지 않다라고 하는 의견을 보았다.

Serializable을 Custom하여 writeObject()와 readObject()를 직접 구현해준다면 reflection방식에서 발생하게 되는 문제들을 줄일 수 있다고 한다.

실제로 그렇게 구현하면 Parcelizable보다 빠르다고 한다.

그럼 정말 뭐가 더 좋고 빠를까?

이렇게 각각의 단점을 읽고나니.. 단정 지을 수 없다고 생각한다.😅

내가 참고한 글과 이 분께서 CustomSerializable을 구현해주셨다.
꼭 참고해보자.

Reference

profile
developer
post-custom-banner

0개의 댓글