Codable
なstruct
データを保存に使うことって結構ないですか?
最近は PropertyListEncoder
なども標準ライブラリに入り、ユーザーデータの保存にも使われているように感じます。
しかしJSON
もPropertyList
もテキスト形式のデータであり、保存すると容量が大きくなります。なので、最大それらの数万倍軽くなるBoxEncoder
を作ってみました。
まず実際どうなるか
Person
というデータを作り、そのデータ10万個を保存した時の値です。
このデータだと4万倍小さくなりました。
Type | File Size |
---|---|
Box | 126 B |
JSON | 5.8 MB |
Plist | 5.4 MB |
// Codableなデータ
struct Person: Codable {
let name: String
let age: UInt8
let birth: Conutry
struct Conutry: Codable {
let name: String
let id: UInt8
}
}
let alice = Person(name: "Alice", age: 16, birth: .init(name: "UK", id: 12))
/// 100000 データ
let people = Array(repeating: alice, count: 100000)
(ランダム性が大きともっと大きくなります。)
使用方法
pod
経由でインストールできます。
pod 'BoxData'
BoxEncoder
と BoxDecoder
は JSONEncoder
や PropertyListEncoder
などと同様に使えるので、すでにこれらを使っていた場合は、名前以外に変更するとことは一切ありません。
do {
// Encoding
let data = try BoxEncoder().encode(people)
// Decoding
let decoded = try BoxDecoder().decode(Array<Person>.self, from: data)
} catch {
print(error)
}
JSON・Plistと異なり、単一のデータも保存できます。
let bool = try encoder.encode(true)
let string = try encoder.encode("Hello Box Format!")
let int = try encoder.encode(1000_0000)
let array = try encoder.encode([12, 13, 14, 15])
なぜ容量が小さいか
- バイトフォーマット
- 構造の保存
-
gzip
圧縮
という理由です。
バイトフォーマット
まず、JSON・Plistなどと異なり、データをバイト列として保存します。更に、適切に型 (UInt8
・Int16
など)を使い分けることで更に容量を軽くできます。
構造の保存
JSON・Plistなどでは配列データなどについても全ての構造を保存しますが、Boxではヘッダに全てのデータ構造を書き込むので繰り返し構造データを書き込むことがありません。
今回のコードは https://github.com/ObuchiYuki/BoxData においてあります。
結構頑張ったので使ってくれると嬉しい