写功能结束时的领域延迟 [英] Realm delay at end of write function

查看:60
本文介绍了写功能结束时的领域延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经以Realm为基础,在Xcode/Swift中构建了一款体育游戏.它正在运行并且正在工作,但是随着时间的流逝,领域事务变得越来越慢,以至于它比我希望的要慢得多.在此示例中,这一点尤其明显.

I've built a sports game in Xcode/Swift using Realm as a base. It's running and working, but realm transactions are getting slower and slower over time, to the point where it's significantly slower than i'd hope. This is particularly evident in this example.

每周都有很多比赛,每个玩家都有为每个比赛创建的GameStat对象(每周创建约2,000个新的GameStats).

Each week there are a number of matches, with each player having a GameStat object created for every match (about 2,000 new GameStats created each week).

class GameStat: Object {         
  @objc dynamic var iden = UUID().uuidString
  @objc dynamic var playerIden = "" // Links to iden of a Player Object
  @objc dynamic var statOne = 0
  @objc dynamic var statTwo = 0
  @objc dynamic var statThree = 0
  etc...

  // Primary Key
  override static func primaryKey() -> String? {
    return "iden"
  }
}

为了防止在每个游戏中写入多个领域,我在Realm(存储在thisGameGameStats数组中)之外创建GameStats,然后在游戏完成后将这些GameStats批量写入领域.批量写入Realm的过程非常缓慢.

To prevent multiple realm writes throughout each game, I create GameStats outside of Realm (store in thisGameGameStats array) and then batch write these GameStats to realm once the game is complete. It is this batch write to Realm which is very slow.

try! realm.write {
  for gmStat in thisGameGameStats {
    realm.add(gmStat)
  }
}

我已经测量了花费的时间,并且我总是在0.05秒后看到"for"循环完成.在前两个循环中,realm.write函数完成没有延迟,但是在几个季节之后(数据库中的c70k条记录),realm.write函数完成又花费了0.50秒.

I've measured time taken and I always see the 'for' loop complete after 0.05 seconds. In the first couple of loops, there is no delay for the realm.write function to complete, however after a couple of seasons (c70k records in database) it takes a further 0.50 seconds for the realm.write function to complete.

这是预料之中的,还是有机会在此处进行优化?

Is this to be expected, or is there an opportunity to optimise here?

通过删除primaryKey,写入变得明显更快,并且随着数据库的增长似乎不会减慢速度.因此,我假设在提交时会发生某种形式的primaryKey排序.

By removing the primaryKey, the write becomes significantly quicker and doesn't seem to slow down as the database grows. I'm assuming there is therefore some form of sort by primaryKey that happens on commit.

推荐答案

这并不完全是答案,但可能会提供一些验证并说明一个有趣的观点.

This isn't exactly an answer but may provide some validatation and illustrate an interesting point.

TL; DR

随着时间的流逝写入大量对象不会对写入时间产生重大影响-在这种情况下,基于现有数据量,您应该不会看到写入时间显着增加.

Writing chunks of objects over time does not have a significant impact on write times - you should not be seeing a significant increase in write times based on the existing volume of data in this use case.

具有设置和测试功能的长版本:

写操作完成后,领域将生成一个通知,因此我们将使用该通知为写操作计时".

When a write has completed, realm will generate a notification so we're using that notification to 'time' the writes.

我们从var类开始,以存储每次写入的开始时间以及一个通知,以跟踪完成的时间

We start with a class var to store the start time of each write and a notification to track when it's done

var startTime = Date()
var gameStatNotificationToken: NotificationToken?

然后我们将一个观察者添加到领域中,该领域将在写入完成后执行,以确定从开始时间到现在之间的经过时间

then we add an observer to realm that will execute when the write has completed that determines the elapsed time between the start time and now

func addObserver {
    if let realm = gGetRealm() { //this just gets a realm
        self.gameStatNotificationToken = realm.observe { notification, realm in
            let elapsed = Date().timeIntervalSince(self.startTime)
            print("\(elapsed)")
        }
    }
}

然后使用代码实际写入数据

Then the code to actually write the data

func writeLotsOfData() {
    autoreleasepool {

        var  gameStatArray = [GameStat]()

        for index in 0..<10000 {
            let stat = GameStat()
            stat.playerIden = "\(index)"
            gameStatArray.append(stat)
        }

    
        if let realm = gGetRealm() {
            self.startTime = Date()
            try! realm.write {
                realm.add(gameStatArray)
            }
        }
    }
}

,然后循环调用上述代码10次;每个循环写入10k,总共写入100k.

and then a loop that calls the above code 10 times; writing 10k per loop, 100k total objects.

func looper() {
    for i in 0..<10 {
        self.writeLotsOfData()
    }
}

因此最终结果显示,随着时间的推移,书写没有增加

So the end result shows no increase in writing over time

0.19487500190734863
0.1404169797897339
0.14565002918243408
0.15493690967559814
0.14426898956298828
0.15933406352996826
0.15379595756530762
0.16700804233551025
0.1598280668258667
0.15421009063720703

编辑

这是我正在使用的GameStat对象-它与问题中的对象相同

Here's the GameStat object I am using - it's identical to the one in the question

class GameStat: Object {
  @objc dynamic var iden = UUID().uuidString
  @objc dynamic var playerIden = "" // Links to iden of a Player Object
  @objc dynamic var statOne = 0
  @objc dynamic var statTwo = 0
  @objc dynamic var statThree = 0

  // Primary Key
  override static func primaryKey() -> String? {
    return "iden"
  }
}

这篇关于写功能结束时的领域延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆