I am trying to bulk insert data into Realm, but it is making it very slow.
this is my code:
let realm = try! Realm()
let group = GroupRealm()
group.id = 1
group.name = "test"
try! realm.write {
realm.add(group)
}
var product = [String:AnyObject]()
product["id"] = "" as AnyObject!
product["code"] = ("") as AnyObject!
product["detail"] = ("") as AnyObject!
product["onHand"] = (0) as AnyObject!
product["price"] = (0) as AnyObject!
product["isSerialized"] = (0) as AnyObject!
product["isLotNumber"] = (0) as AnyObject!
var groupProduct = [String:AnyObject]()
groupProduct["group"] = group as AnyObject!
for r in 0..<300 {
realm.beginWrite()
for i in 0..<100 {
product["id"] = "\(i)-\(r)" as AnyObject!
realm.create(ProductRealm.self, value: product, update: true)
groupProduct["id"] = "\(i)-\(r)" as AnyObject!
groupProduct["product"] = product as AnyObject!
realm.create(GroupProductRealm.self, value: groupProduct, update: true)
}
try! realm.commitWrite()
}
The objects I am using are these:
class ProductRealm: Object {
public dynamic var id: String = ""
public dynamic var code: String = ""
public dynamic var detail: String = ""
public dynamic var onHand: Int = 0
public dynamic var price: Double = 0
public dynamic var isSerialized: Int = 0
public dynamic var isLotNumber: Int = 0
override static func primaryKey() -> String? {
return "id"
}
}
class GroupProductRealm: Object {
public dynamic var id = ""
public dynamic var group: GroupRealm!
public dynamic var product: ProductRealm!
override static func primaryKey() -> String? {
return "id"
}
}
class GroupRealm: Object {
public dynamic var id = 1
public dynamic var name = ""
public dynamic var update = Date()
override static func primaryKey() -> String? {
return "id"
}
}
Testing on my iphone 5s to insert 30000 records takes over 30 seconds, while on an old project I have with sqlite it takes around 16 seconds.
I've read that realm is much faster at this than sqlite, so I know it's my mistake, but I can't find the D:
Well after many tests I found a way to reduce the time to only 1-2 seconds of data creation to insert and 7-9 seconds of insertion (it can be lowered more if fewer records are shown, for example if I show when 1000 insertions is reduced to 4-6 seconds).
The first thing I have to say is that the objects were wrong, although in sqlite the many-to-many relationships are made with an auxiliary table, here it is completely superfluous, since one can insert the same record several times in an array, for so the objects remain like this:
This means that unlike sqlite it is only necessary to insert the data in a single "table" and its references in the other "table" which makes it much simpler and improves performance a bit, however the insertion times They were still very high.
After many tests it occurred to me to use the jsonObject to insert, since the idea is to bring these records from a server, and to my surprise this greatly reduced the insertion time compared to the dictionaries, so the final code would look like this :
Well I'll leave it that way, but if you find a way to optimize it I'd really appreciate it.
What is mainly making it take longer to insert it is opening and closing several
write transactions
within thefor
.This would be an inefficient or incorrect way:
Instead, this other would be the most efficient and correct:
For your particular case, I would do the following: