SlideShare a Scribd company logo
1 of 73
Download to read offline
Realm은 어떻게 효율적인 

데이터베이스를 만들었나?
Leonardo YongUk Kim

Java team
첫번째 비결

Zero copy
Zero copy

“최대한 복제를 미루는 것입니다.”
왜 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;
}
}
제로 카피 없는 세상을 생각해 봅시다.
왜 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 파서가 채워줘야 해요.
왜 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;
}
너가 뭘 쓸지 몰라서 다 준비했어요.
왜 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;
}
너가 뭘 쓸지 몰라서 다 준비했어요.
수화라고 번역합니다. 객체의 필드를 채우는 일입니다.
왜 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~!
왜 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값의 변환과 설정은 필요없는 것 아닌가?
왜 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에 기록합니다.
보일러플레이트
보일러플레이트
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);
}
}
프로그래머에게 직관적인 코드
보일러플레이트
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);
}
}
프로그래머에게 비관적인 코드
꼭 이렇게 짜야하나요?
보일러플레이트
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를 상속 받습니다.
반복적인 작업은 기계에게 맡겨야 합니다.
Man vs Code
City
CityRealmProxy
사용자의 원본 객체 (RealmObject)
기계가 생성한 객체 (RealmProxy)
어노테이션 프로세싱 툴 (APT)
Man vs Code
AbstractProcessor

+process(annotations, roundEnv)
RealmProcessor
RealmObject
RealmProxy
RealmObject
RealmProxy
RealmObject
RealmProxy
Man vs Code
writer.emitAnnotation("Override")
.beginMethod(
"void", // return type
"copy", // method name
EnumSet.of(Modifier.PROTECTED, Modifier.FINAL), // modifiers
"ColumnInfo", "rawSrc", "ColumnInfo", "rawDst"); // parameters
writer.emitStatement("final %1$s src = (%1$s) rawSrc", columnInfoClassName());
writer.emitStatement("final %1$s dst = (%1$s) rawDst", columnInfoClassName());
for (VariableElement variableElement : metadata.getFields()) {
writer.emitStatement("dst.%1$s = src.%1$s", columnIndexVarName(variableElement));
}
writer.endMethod();
Man vs Code




당신은 용자
코드도 찍어내면 그만?
내가 코드를 짜는 건지 코드가 날 짜는 건지.
튜토리얼이 많은 애가 개발이 잘 안돼.
그래도 스퀘어가 제일 낫지 않나?
APT가 해법인가?
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);
}
}
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을 쓰지 않을까요?
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은 어떤 부가 작업을 하고 있을까요?
바이트 코드 뒤집기
바이트 코드 뒤집기
City

name
CityRealmProxy
CityRealmProxyInterface



+realmGet$name: String

+realmSet$name(name)
ZeroCopy관련 객체를 위한 인터페이스
name 필드에 접근하는 모든 코드 대신 realmGet$name과 realmSet$name이 호출되도록 변조합니다.
realmGet$name과 realmSet$name를 오버라이드해서 Zero copy 부분을 구현합니다.
바이트 코드 뒤집기
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 아래 생성됩니다.
바이트 코드 뒤집기
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;
}
}
바이트 코드 뒤집기
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 필드에 대한 접근은 모두 게터와 세터 호출로 변경됩니다.
바이트 코드 뒤집기
City
CIty
사용자가 생성한 객체
바이트 코드 변조된 객체
Transformer
바이트 코드 뒤집기
class RealmTransformer extends Transform {
@Override
void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput>
referencedInputs,
TransformOutputProvider outputProvider, boolean isIncremental)
throws IOException, TransformException, InterruptedException {
…
}
}
이 트랜스포머가 필드에 대한 접근들을 모두 Realm의 게터와 세터로 변조합니다.
바이트 코드 뒤집기
중간 정도 난이도의 도구. Realm이 사용.
다른 DB도 Zero copy?
다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
이 영역까지만 lazy하게 미룰 수 있음.
다른 DB도 Zero copy?
SQLite
시스템 적인 경계
Object
Object
Object
Object
Object
Object
ORM
경계를 넘어서 lazy한 처리는 어려움.
더 많은 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;
더 많은 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 은 오프셋도 리미트도 없습니다.
더 많은 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;
이 시점에서는 실제 데이터를 받아오지 않습니다.
실제 데이터를 가지고 있지 않기 때문에 특수한 리스트 구조를 가지고 있습니다.
더 많은 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;
이 시점에 첫 번째 사람에 대한 메타 데이터만 가지고 옵니다.
더 많은 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만 접근합니다.
더 많은 Zero copy 가능성
조금 더 빨라지기 위해
조금 더 빨라지기 위해
final RealmResults<Person> people = realm.where(Person.class).findAll();
for (Person person : people) {
final String name = person.name;
}
객체의 전체 필드가 필요한 경우는 드뭅니다.
조금 더 빨라지기 위해
리프가 10번째 Row까지 가진다는 것을 의미
리프는 보통 연속된 Array
Row에 속한 모든 Column
조금 더 빨라지기 위해
인접한 데이터는 name이 아니다.
조금 더 빨라지기 위해
캐시 라인
캐시 히트 캐시 미스
조금 더 빨라지기 위해
캐시 라인
조금 더 빨라지기 위해
캐시 라인
캐시 히트 캐시 미스
조금 더 빨라지기 위해
리프가 4번째 컬럼까지 가진다는 것을 의미
동질적인 데이터이기에 예측가능한 사이즈
Group (DB와 같은 개념)
Table
Column B-tree
Root
Root가 있는 이유?
Root가 있는 이유?
Root
전체 Group을 하나의 스냅샷으로 인지.
Root가 있는 이유?
현재 버전을 포인팅
Root
현재 버전
삭제될 과거 버전
Git, 현대적인 DBMS에서 사용.
Root가 있는 이유?
Root
다른 사용자는 현재 버전에 Lock 없이 접근.
새 버전을 작성중.
Root가 있는 이유?
Root
새로 작성된 버전으로 옮겨가는 것만 락이 필요합니다.
Root
다른 사용자는 여전히 이전 버전에 접근 중.
루트를 이동
Root가 있는 이유?
프로그래머에게 직관적이지는 않습니다.
이전 버전을 읽을 가능성?
이전 버전을 읽을 가능성?
Root
다른 사용자는 현재 버전에 Lock 없이 접근.
새 버전을 작성중.
이전 버전을 읽을 가능성?
Person 객체 (Leonardo)

v1
Person 객체 (Leonardo)

v1
Person 객체 (Leonardo)

v2
1. 스레드 A에서 Person 객체 업데이트.
2. 업데이트 내역이 전파.
Person 객체 (Leonardo)

v2
3. 스레드 B의 라이브 객체가 자동 업데이트.
3. 스레드 B의 객체의 리스너에게 모두 업데이트 내용을 통보.
추가적인 최적화
추가적인 최적화
배열은 얼마나 많은 공간을 차지할까?
Root
추가적인 최적화
votes가 최대 1인 경우Boolean 타입이 가장 효율적으로 저장됩니다.
추가적인 최적화
최대 값이 2로 변경되었습니다.
추가적인 최적화
최대 값이 5로 변경되었습니다.
추가적인 최적화
Root
개별 노드는 3개의 배열을 사용합니다.
유연하지만 오버헤드가 있습니다.
추가적인 최적화
만약에 데이터가 뒤로만 추가된다면 더 최적화를 할 수 있습니다.
모든 노드가 다 차있다면 처음과 마지막 인덱스만 있으면 됩니다.
추가적인 최적화
물론 이러한 꿈은 삽입과 삭제가 이뤄지면 물거품이 됩니다.
모든 노드가 다 차있다면 처음과 마지막 인덱스만 있으면 됩니다.
흥미로운가요?
기회는 여러분에게 열려있습니다.




















Realm을 바로 사용하실 수 있습니다.
















최신 모바일 기술은 Realm에서
Thank you

More Related Content

What's hot

파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409Yong Joon Moon
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)beom kyun choi
 
안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법mosaicnet
 
안드로이드 개발자를 위한 스위프트
안드로이드 개발자를 위한 스위프트안드로이드 개발자를 위한 스위프트
안드로이드 개발자를 위한 스위프트병한 유
 
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 양 한빛
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기 Yong Joon Moon
 
일단 시작하는 코틀린
일단 시작하는 코틀린일단 시작하는 코틀린
일단 시작하는 코틀린Park JoongSoo
 
EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overviewyongwoo Jeon
 
Fluent Python - Chapter 8
Fluent Python - Chapter 8Fluent Python - Chapter 8
Fluent Python - Chapter 8Sunghyun Lee
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for BioinformaticsHyungyong Kim
 
골때리는 자바스크립트 발표자료
골때리는 자바스크립트 발표자료골때리는 자바스크립트 발표자료
골때리는 자바스크립트 발표자료욱진 양
 
TenforFlow Internals
TenforFlow InternalsTenforFlow Internals
TenforFlow InternalsKiho Hong
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성HyeonSeok Choi
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple OverviewKim Hunmin
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Yong Joon Moon
 
파이썬 유용한 라이브러리
파이썬 유용한 라이브러리파이썬 유용한 라이브러리
파이썬 유용한 라이브러리SeongHyun Ahn
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지SeongHyun Ahn
 

What's hot (20)

파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법
 
안드로이드 개발자를 위한 스위프트
안드로이드 개발자를 위한 스위프트안드로이드 개발자를 위한 스위프트
안드로이드 개발자를 위한 스위프트
 
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기
 
일단 시작하는 코틀린
일단 시작하는 코틀린일단 시작하는 코틀린
일단 시작하는 코틀린
 
EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overview
 
Fluent Python - Chapter 8
Fluent Python - Chapter 8Fluent Python - Chapter 8
Fluent Python - Chapter 8
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for Bioinformatics
 
골때리는 자바스크립트 발표자료
골때리는 자바스크립트 발표자료골때리는 자바스크립트 발표자료
골때리는 자바스크립트 발표자료
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
TenforFlow Internals
TenforFlow InternalsTenforFlow Internals
TenforFlow Internals
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 
Fp basic-kotlin
Fp basic-kotlinFp basic-kotlin
Fp basic-kotlin
 
파이썬 유용한 라이브러리
파이썬 유용한 라이브러리파이썬 유용한 라이브러리
파이썬 유용한 라이브러리
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지
 
Java start01 in 2hours
Java start01 in 2hoursJava start01 in 2hours
Java start01 in 2hours
 

Similar to Realm은 어떻게 효율적인 데이터베이스를 만들었나?

[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_databaseNAVER D2
 
[Swift] Protocol (2/2)
[Swift] Protocol (2/2)[Swift] Protocol (2/2)
[Swift] Protocol (2/2)Bill Kim
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2도현 김
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part oneJi Hun Kim
 
Python vs Java @ PyCon Korea 2017
Python vs Java @ PyCon Korea 2017Python vs Java @ PyCon Korea 2017
Python vs Java @ PyCon Korea 2017Insuk (Chris) Cho
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++KWANGIL KIM
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)JiandSon
 
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613KTH, 케이티하이텔
 
2시간만에 자바 데이터처리를 쉽게 배우고 싶어요.
2시간만에  자바 데이터처리를 쉽게 배우고 싶어요.2시간만에  자바 데이터처리를 쉽게 배우고 싶어요.
2시간만에 자바 데이터처리를 쉽게 배우고 싶어요.Kenu, GwangNam Heo
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍Young-Beom Rhee
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나Astin Choi
 
Java Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJava Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJavajigi Jaesung
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선daewon jeong
 
Multithread design pattern
Multithread design patternMultithread design pattern
Multithread design pattern종빈 오
 
자바8 람다 나머지 공개
자바8 람다 나머지 공개자바8 람다 나머지 공개
자바8 람다 나머지 공개Sungchul Park
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스SeoYeong
 
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...Isaac Jeon
 

Similar to Realm은 어떻게 효율적인 데이터베이스를 만들었나? (20)

[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database
 
[Swift] Protocol (2/2)
[Swift] Protocol (2/2)[Swift] Protocol (2/2)
[Swift] Protocol (2/2)
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
 
Python vs Java @ PyCon Korea 2017
Python vs Java @ PyCon Korea 2017Python vs Java @ PyCon Korea 2017
Python vs Java @ PyCon Korea 2017
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 자바8 람다 나머지 이야기 (박성철)
 
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
 
2시간만에 자바 데이터처리를 쉽게 배우고 싶어요.
2시간만에  자바 데이터처리를 쉽게 배우고 싶어요.2시간만에  자바 데이터처리를 쉽게 배우고 싶어요.
2시간만에 자바 데이터처리를 쉽게 배우고 싶어요.
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나
 
Java Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte CodeJava Virtual Machine, Call stack, Java Byte Code
Java Virtual Machine, Call stack, Java Byte Code
 
GraphQL 적용기
GraphQL 적용기GraphQL 적용기
GraphQL 적용기
 
Scala for play
Scala for playScala for play
Scala for play
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선
 
Multithread design pattern
Multithread design patternMultithread design pattern
Multithread design pattern
 
자바8 람다 나머지 공개
자바8 람다 나머지 공개자바8 람다 나머지 공개
자바8 람다 나머지 공개
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스
 
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
 

More from Leonardo YongUk Kim

Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래Leonardo YongUk Kim
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계Leonardo YongUk Kim
 
MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지Leonardo YongUk Kim
 
A brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinA brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinLeonardo YongUk Kim
 
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?Leonardo YongUk Kim
 
Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Leonardo YongUk Kim
 
Veni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle PluginVeni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle PluginLeonardo YongUk Kim
 

More from Leonardo YongUk Kim (20)

Compose Multiplatform 101
Compose Multiplatform 101Compose Multiplatform 101
Compose Multiplatform 101
 
Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계
 
MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지MVC부터 MVVM, 단방향 데이터 흐름까지
MVC부터 MVVM, 단방향 데이터 흐름까지
 
Anatomy of Realm
Anatomy of RealmAnatomy of Realm
Anatomy of Realm
 
PublishSubject
PublishSubjectPublishSubject
PublishSubject
 
Tensorflow 101
Tensorflow 101Tensorflow 101
Tensorflow 101
 
Realm과 RxJava
Realm과 RxJavaRealm과 RxJava
Realm과 RxJava
 
A brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinA brief introduction to Realm with Kotlin
A brief introduction to Realm with Kotlin
 
Realm Java
Realm JavaRealm Java
Realm Java
 
역시 Redux
역시 Redux역시 Redux
역시 Redux
 
3D Graphics 101
3D Graphics 1013D Graphics 101
3D Graphics 101
 
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
오픈 소스로 취업하기: 나는 어떻게 오픈 소스를 하다 렘 개발자가 되었나?
 
Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스
 
React Everywhere
React EverywhereReact Everywhere
React Everywhere
 
React Redux React Native
React Redux React NativeReact Redux React Native
React Redux React Native
 
Veni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle PluginVeni, Vide, Built: Android Gradle Plugin
Veni, Vide, Built: Android Gradle Plugin
 
A brief guide to android gradle
A brief guide to android gradleA brief guide to android gradle
A brief guide to android gradle
 
Modern android
Modern androidModern android
Modern android
 
Butter android views
Butter android viewsButter android views
Butter android views
 

Realm은 어떻게 효율적인 데이터베이스를 만들었나?

  • 1. Realm은 어떻게 효율적인 
 데이터베이스를 만들었나? Leonardo YongUk Kim Java team
  • 2.
  • 4. Zero copy
 “최대한 복제를 미루는 것입니다.”
  • 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를 상속 받습니다.
  • 16. 반복적인 작업은 기계에게 맡겨야 합니다.
  • 17. Man vs Code City CityRealmProxy 사용자의 원본 객체 (RealmObject) 기계가 생성한 객체 (RealmProxy) 어노테이션 프로세싱 툴 (APT)
  • 18. Man vs Code AbstractProcessor
 +process(annotations, roundEnv) RealmProcessor RealmObject RealmProxy RealmObject RealmProxy RealmObject RealmProxy
  • 19. Man vs Code writer.emitAnnotation("Override") .beginMethod( "void", // return type "copy", // method name EnumSet.of(Modifier.PROTECTED, Modifier.FINAL), // modifiers "ColumnInfo", "rawSrc", "ColumnInfo", "rawDst"); // parameters writer.emitStatement("final %1$s src = (%1$s) rawSrc", columnInfoClassName()); writer.emitStatement("final %1$s dst = (%1$s) rawDst", columnInfoClassName()); for (VariableElement variableElement : metadata.getFields()) { writer.emitStatement("dst.%1$s = src.%1$s", columnIndexVarName(variableElement)); } writer.endMethod();
  • 20. Man vs Code 
 
 당신은 용자 코드도 찍어내면 그만? 내가 코드를 짜는 건지 코드가 날 짜는 건지. 튜토리얼이 많은 애가 개발이 잘 안돼. 그래도 스퀘어가 제일 낫지 않나?
  • 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은 어떤 부가 작업을 하고 있을까요?
  • 26. 바이트 코드 뒤집기 City name CityRealmProxy CityRealmProxyInterface
 
 +realmGet$name: String +realmSet$name(name) ZeroCopy관련 객체를 위한 인터페이스 name 필드에 접근하는 모든 코드 대신 realmGet$name과 realmSet$name이 호출되도록 변조합니다. realmGet$name과 realmSet$name를 오버라이드해서 Zero copy 부분을 구현합니다.
  • 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 필드에 대한 접근은 모두 게터와 세터 호출로 변경됩니다.
  • 30. 바이트 코드 뒤집기 City CIty 사용자가 생성한 객체 바이트 코드 변조된 객체 Transformer
  • 31. 바이트 코드 뒤집기 class RealmTransformer extends Transform { @Override void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException { … } } 이 트랜스포머가 필드에 대한 접근들을 모두 Realm의 게터와 세터로 변조합니다.
  • 32. 바이트 코드 뒤집기 중간 정도 난이도의 도구. Realm이 사용.
  • 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만 접근합니다.
  • 42. 더 많은 Zero copy 가능성
  • 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
  • 46. 조금 더 빨라지기 위해 인접한 데이터는 name이 아니다.
  • 47. 조금 더 빨라지기 위해 캐시 라인 캐시 히트 캐시 미스
  • 48. 조금 더 빨라지기 위해 캐시 라인
  • 49. 조금 더 빨라지기 위해 캐시 라인 캐시 히트 캐시 미스
  • 50. 조금 더 빨라지기 위해 리프가 4번째 컬럼까지 가진다는 것을 의미 동질적인 데이터이기에 예측가능한 사이즈
  • 51. Group (DB와 같은 개념) Table Column B-tree Root
  • 53. Root가 있는 이유? Root 전체 Group을 하나의 스냅샷으로 인지.
  • 54. Root가 있는 이유? 현재 버전을 포인팅 Root 현재 버전 삭제될 과거 버전 Git, 현대적인 DBMS에서 사용.
  • 55. Root가 있는 이유? Root 다른 사용자는 현재 버전에 Lock 없이 접근. 새 버전을 작성중.
  • 56. Root가 있는 이유? Root 새로 작성된 버전으로 옮겨가는 것만 락이 필요합니다. Root 다른 사용자는 여전히 이전 버전에 접근 중. 루트를 이동
  • 57. Root가 있는 이유? 프로그래머에게 직관적이지는 않습니다.
  • 59. 이전 버전을 읽을 가능성? Root 다른 사용자는 현재 버전에 Lock 없이 접근. 새 버전을 작성중.
  • 60. 이전 버전을 읽을 가능성? Person 객체 (Leonardo)
 v1 Person 객체 (Leonardo) v1 Person 객체 (Leonardo)
 v2 1. 스레드 A에서 Person 객체 업데이트. 2. 업데이트 내역이 전파. Person 객체 (Leonardo)
 v2 3. 스레드 B의 라이브 객체가 자동 업데이트. 3. 스레드 B의 객체의 리스너에게 모두 업데이트 내용을 통보.
  • 62. 추가적인 최적화 배열은 얼마나 많은 공간을 차지할까? Root
  • 63. 추가적인 최적화 votes가 최대 1인 경우Boolean 타입이 가장 효율적으로 저장됩니다.
  • 64. 추가적인 최적화 최대 값이 2로 변경되었습니다.
  • 65. 추가적인 최적화 최대 값이 5로 변경되었습니다.
  • 66. 추가적인 최적화 Root 개별 노드는 3개의 배열을 사용합니다. 유연하지만 오버헤드가 있습니다.
  • 67. 추가적인 최적화 만약에 데이터가 뒤로만 추가된다면 더 최적화를 할 수 있습니다. 모든 노드가 다 차있다면 처음과 마지막 인덱스만 있으면 됩니다.
  • 68. 추가적인 최적화 물론 이러한 꿈은 삽입과 삭제가 이뤄지면 물거품이 됩니다. 모든 노드가 다 차있다면 처음과 마지막 인덱스만 있으면 됩니다.
  • 71. Realm을 바로 사용하실 수 있습니다.