出乎意料的是Realm文件大小很大

Cil*_*las 5 filesize realm swift

这个问题是关于使用两种不同的方法将对象插入Realm.我注意到第一种方法要快得多,但与第二种方法相比,尺寸结果是巨大的.两种方法之间的差异是将写入事务移到外部和for循环内部.

// Create realm file
let realm = try! Realm(fileURL: banco_url!)
Run Code Online (Sandbox Code Playgroud)

当我添加这样的对象时,Realm文件增长到75.5MB:

try! realm.write {
    for i in 1...40000 {
        let new_realm_obj = realm_obj(value: ["id" : incrementID(),
                                              "a": "123",
                                              "b": 12.12,
                                              "c": 66,
                                              "d": 13.13,
                                              "e": 0.6,
                                              "f": "01100110",
                                              "g": DateTime,
                                              "h": 3])

        realm.add(new_realm_obj)
        print(" \(i) Added")
    }
}
Run Code Online (Sandbox Code Playgroud)

当我添加这样的对象时,Realm文件只增长到5.5MB:

for i in 1...40000 {
    let new_realm_obj = realm_obj(value: ["id" : incrementID(),
                                          "a": "123",
                                          "b": 12.12,
                                          "c": 66,
                                          "d": 13.13,
                                          "e": 0.6,
                                          "f": "01100110",
                                          "g": DateTime,
                                          "h": 3])
    try! realm.write {
        realm.add(new_realm_obj)
        print(" \(i) Added")
    }
}
Run Code Online (Sandbox Code Playgroud)

我的类添加到领域文件

class realm_obj: Object {
    dynamic var id = Int()
    dynamic var a = ""
    dynamic var b = 0.0
    dynamic var c = Int8()
    dynamic var d = 0.0
    dynamic var e = 0.0
    dynamic var f = ""
    dynamic var g = Date()
    dynamic var h = Int8()
}
Run Code Online (Sandbox Code Playgroud)

自动增量功能

func incrementID() -> Int {
    let realm = try! Realm(fileURL: banco_url!)
    return (realm.objects(realm_obj.self).max(ofProperty: "id") as Int? ?? 0) + 1
}
Run Code Online (Sandbox Code Playgroud)

有没有更好或正确的方法来做到这一点?为什么在这些情况下我会得到不同的文件大小?

bda*_*ash 8

在单个事务中添加所有对象时的大文件大小是由于Realm的事务日志子系统与Realm的大型blob内存分配算法之间的不幸交互.Realm的内存布局算法要求文件大小至少是Realm文件中存储的最大单个Blob大小的8倍.总结在单个事务期间所做的修改的事务日志条目作为Blob存储在Realm文件中.

在一个事务中添加40,000个对象时,最终会得到一个大小约为5MB的事务日志条目.这意味着文件的大小必须至少为40MB才能存储.(我不太确定它的最终结果几乎是那个大小的两倍.可能是blob大小在某条线的某个位置被四舍五入到......)

当您在40,000个事务中添加一个对象时,您仍然只有一个事务日志条目,这次它的大小是一百个左右.发生这种情况是因为当Realm提交事务时,它会尝试在为新条目分配空间之前首先回收未使用的事务日志条目.由于Realm文件未在其他位置打开,因此可以在执行每个新提交时回收先前的条目.

realm/realm-core#2343跟踪改进Realm存储事务日志条目的方式,以避免您看到的重要位置.

现在我的建议是分割两种方法之间的差异,并为每个写入事务添加对象组.这将通过增加提交次数来折衷一点性能,但会通过减少您创建的最大事务日志条目的大小来减少内存布局算法的影响.从快速测试中,提交每2,000个对象会导致文件大小约为4MB,同时比在单独的写入事务中添加每个对象要快得多.