5. 왜 Zero copy인가?
public class City {
private String name;
private long votes;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
}
제로 카피 없는 세상을 생각해 봅시다.
6. 왜 Zero copy인가?
public class City {
private String name;
private long votes;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
}
ORM이나 JSON 파서가 채워줘야 해요.
ORM이나 JSON 파서가 채워줘야 해요.
7. 왜 Zero copy인가?
public class City {
private String name;
private long votes;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
}
public List<City> hydrate() {
List<City> results = new ArrayList<>();
while (hasNextItem) {
City c = new City();
c.setName(name);
c.setVotes(votes);
results.add(c);
}
return results;
}
너가 뭘 쓸지 몰라서 다 준비했어요.
8. 왜 Zero copy인가?
public List<City> hydrate() {
List<City> results = new ArrayList<>();
while (hasNextItem) {
City c = new City();
c.setName(name);
c.setVotes(votes);
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
results.add(c);
}
return results;
}
너가 뭘 쓸지 몰라서 다 준비했어요.
수화라고 번역합니다. 객체의 필드를 채우는 일입니다.
9. 왜 Zero copy인가?
public List<City> hydrate() {
List<City> results = new ArrayList<>();
while (hasNextItem) {
City c = new City();
c.setName(String.valueOf(name));
c.setVotes(Integer.parseInt(votes));
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
/* invoke other setters */
results.add(c);
}
return results;
}
어쩌면 매번 변환이 필요할지 몰라Yo~!
10. 왜 Zero copy인가?
public class City {
private String name;
private long votes;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
}
만약에 사용자가 getName만 필요하면?
votes값의 변환과 설정은 필요없는 것 아닌가?
11. 왜 Zero copy인가?
public class City {
private String name;
private long votes;
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
}
row에서 해당 column만 이제 가져옵시다.
name을 채우지 맙시다.
row의 해당 column에 기록합니다.
13. 보일러플레이트
public class City {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class City {
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
프로그래머에게 직관적인 코드
14. 보일러플레이트
public class City {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class LazyCity {
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
프로그래머에게 비관적인 코드
꼭 이렇게 짜야하나요?
15. 보일러플레이트
public class City extends RealmObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class CityRealmProxy extends City{
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
반복적인 작업은 기계에게 맡겨야 합니다.
생성된 클래스는 모두 RealmProxy가 붙습니다.Realm 객체는 RealmObject를 상속 받습니다.
22. APT가 해법인가?
public class City extends RealmObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class CityRealmProxy extends City {
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
23. APT가 해법인가?
public class City extends RealmObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class CityRealmProxy extends City {
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
name이란 필드에 대해 getName과 setName을 쓰지 않을까요?
24. APT가 해법인가?
public class City extends RealmObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class CityRealmProxy extends City {
private final int COLUMN_NAME = 0;
public String getName() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void setName(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
City의 getName은 어떤 부가 작업을 하고 있을까요?
City의 setName은 어떤 부가 작업을 하고 있을까요?
27. 바이트 코드 뒤집기
public class CityRealmProxy extends City implements CityRealmProxyInterface {
private final int COLUMN_NAME = 0;
public String realmGet$name() {
return (String) getRow().getSting(COLUMN_NAME);
}
public void realmSet$Name(String name) {
getRow().setString(COLUMN_NAME, name);
}
}
내부용 게터와 세터는 RealmProxy 아래 생성됩니다.
28. 바이트 코드 뒤집기
public class City implements CityRealmProxyInterface {
private String name;
public String getName() {
return (String) realmGet$name();
}
public void setName(String name) {
realmSet$name(name);
}
public String realmGet$name() {
return name;
}
public void realmSet$Name(String name) {
this.name = name;
}
}
public class City extends RealmObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
29. 바이트 코드 뒤집기
public class City implements CityRealmProxyInterface {
public String name;
public String realmGet$name() {
return name;
}
public void realmSet$Name(String name) {
this.name = name;
}
}
public class City extends RealmObject {
public String name;
}
name 필드에 대한 접근은 모두 게터와 세터 호출로 변경됩니다.
34. 다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
35. 다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
이 영역까지만 lazy하게 미룰 수 있음.
36. 다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
경계를 넘어서 lazy한 처리는 어려움.
37. 더 많은 Zero copy 가능성
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = realm.createObject(Person.class);
person.setId(1);
person.setName("Young Person");
person.setAge(14);
}
});
final RealmResults<Person> people = realm.where(Person.class).findAll();
final Person person = people.first();
final String name = person.name;
38. 더 많은 Zero copy 가능성
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = realm.createObject(Person.class);
person.setId(1);
person.setName("Young Person");
person.setAge(14);
}
});
final RealmResults<Person> people = realm.where(Person.class).findAll();
final Person person = people.first();
final String name = person.name;
Realm 은 오프셋도 리미트도 없습니다.
39. 더 많은 Zero copy 가능성
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = realm.createObject(Person.class);
person.setId(1);
person.setName("Young Person");
person.setAge(14);
}
});
final RealmResults<Person> people = realm.where(Person.class).findAll();
final Person person = people.first();
final String name = person.name;
이 시점에서는 실제 데이터를 받아오지 않습니다.
실제 데이터를 가지고 있지 않기 때문에 특수한 리스트 구조를 가지고 있습니다.
40. 더 많은 Zero copy 가능성
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = realm.createObject(Person.class);
person.setId(1);
person.setName("Young Person");
person.setAge(14);
}
});
final RealmResults<Person> people = realm.where(Person.class).findAll();
final Person person = people.first();
final String name = person.name;
이 시점에 첫 번째 사람에 대한 메타 데이터만 가지고 옵니다.
41. 더 많은 Zero copy 가능성
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Person person = realm.createObject(Person.class);
person.setId(1);
person.setName("Young Person");
person.setAge(14);
}
});
final RealmResults<Person> people = realm.where(Person.class).findAll();
final Person person = people.first();
final String name = person.name;
이 시점에 첫 번째 사람의 정보 중 name만 접근합니다.
44. 조금 더 빨라지기 위해
final RealmResults<Person> people = realm.where(Person.class).findAll();
for (Person person : people) {
final String name = person.name;
}
객체의 전체 필드가 필요한 경우는 드뭅니다.
45. 조금 더 빨라지기 위해
리프가 10번째 Row까지 가진다는 것을 의미
리프는 보통 연속된 Array
Row에 속한 모든 Column
59. 이전 버전을 읽을 가능성?
Root
다른 사용자는 현재 버전에 Lock 없이 접근.
새 버전을 작성중.
60. 이전 버전을 읽을 가능성?
Person 객체 (Leonardo)
v1
Person 객체 (Leonardo)
v1
Person 객체 (Leonardo)
v2
1. 스레드 A에서 Person 객체 업데이트.
2. 업데이트 내역이 전파.
Person 객체 (Leonardo)
v2
3. 스레드 B의 라이브 객체가 자동 업데이트.
3. 스레드 B의 객체의 리스너에게 모두 업데이트 내용을 통보.