Swift 大尺寸json的领域数据插入耗时超过7分钟

Swift 大尺寸json的领域数据插入耗时超过7分钟,swift,insert,realm,alamofire,swifty-json,Swift,Insert,Realm,Alamofire,Swifty Json,我使用Alamofire下载大约7MB的大json数据,并使用RealmSwift将数据存储在realmobject和SwiftyJSON上进行解析。在下载完json后,我的领域对象插入速度似乎非常慢。我的错误代码有问题吗?请指导我 首先,我将展示最简单的Json: { { "Start" : "40000", "End" : "1000000", "Name" : "Smith", "Address" : "New Yor

我使用Alamofire下载大约7MB的大json数据,并使用RealmSwift将数据存储在realmobject和SwiftyJSON上进行解析。在下载完json后,我的领域对象插入速度似乎非常慢。我的错误代码有问题吗?请指导我

首先,我将展示最简单的Json:

{
    {
        "Start" : "40000",
        "End" : "1000000",
        "Name" : "Smith",
        "Address" : "New York"
    },{...},more than 7000 records...
}
这是我的AlamofireAPI协议

import Foundation
import Alamofire
import SwiftyJSON

protocol RequestDataAPIProtocol{
    func didSuccessDownloadingData(results:JSON,statusCode : Int)
    func didFailDownloadingData(err : NSError)
}

class RequestDataAPI{

var delegate : RequestDataAPIProtocol
init(delegate: RequestDataAPIProtocol){
    self.delegate=delegate
}

func post(requestURL:String,param:[String:String]){
    Alamofire.request(.GET, requestURL, parameters: param)
        .validate(statusCode: [200,500])
        .responseJSON(completionHandler: { (response: Response<AnyObject, NSError>) -> Void in
            if let error = response.result.error {
                self.delegate.didFailDownloadingData(error)
            } else if let jsonObject: AnyObject = response.result.value {
                let json = JSON(jsonObject)
                self.delegate.didSuccessDownloadingData(json,statusCode: (response.response?.statusCode)!)
            }
        })
}

func doRequestSiteData(token : String){
    post(REQUEST_DATA,param:["data":"All","token":token])
}

}
这是我的领域模型对象

import Foundation
import RealmSwift

class UserList: Object {

     dynamic var start : String = ""
     dynamic var end : String = ""
     dynamic var name : String = ""
     dynamic var address : String = ""

}
最后一个代码,视图控制器

class ViewController : UIViewController , RequestDataAPIProtocol{
       var dbHelper = DBHelper()
       var requestDataAPI : RequestDataAPI!

       override func viewDidLoad() {
           super.viewDidLoad()
           requestDataAPI = RequestDataAPI(delegate : self)
       }

       override func viewDidAppear(animated : Bool){
            //assume there is one token to request data
            requestDataAPI.doRequestSiteData(token)
       }

       func didSuccessDownloadingData(results: JSON, statusCode: Int){
        dispatch_async(dispatch_get_main_queue(), {
            print("Downloaded JSON")
            switch statusCode{
            case 200 :
               if results.count > 0{
                   if let users = results.array {
                      for user in users{
                         let userList=UserList()
                         userList.start=user["Start”].stringValue
                         userList.end=user[“End”].stringValue
                         userList.name=user[“Name”].stringValue
                         userList.address =user[“Address”].stringValue
                         self.dbHelper.insertUserData(userList)
                      }
                   }
               }
               // took about more than 7 mins
               print(“Insertion Done”)
               break

           case 500,401,400 :
               //TODO: 
           default : break
           }
        })
    }
}
我知道描述所有代码步骤非常愚蠢,我尽可能简单地编写了将json数据插入领域swift的工作流程。

我只想让大家知道,在处理这么多json数据时,我的工作流程是好是坏,还有插入

我问这个问题的原因是数据插入大约需要7分钟才能完成

所以,我真的需要帮助,使优化在我的代码

有导游吗


更新:我使用RequestDataAPI中的委托和协议,我从JamesQueue教程中学习了这种风格,因为我是一名初学者,仍在学习Swift.ViewController已更新。这是我的整个过程细节,没有更多的代码了。编辑我的问题或答案有助于代码优化。

insertUserData
方法在循环中多次打开事务。提交事务是有点昂贵的操作

您是否可以尝试在循环之外打开/提交事务? 换句话说,在进入循环之前打开事务,并在循环结束后提交一次事务。例如:

if results.count > 0 {
    if let users = results.array {
        let realm = try! Realm()
        try realm.write {
            for user in users{
                let userList=UserList()
                userList.start=user["Start”].stringValue
                userList.end=user[“End”].stringValue
                userList.name=user[“Name”].stringValue
                userList.address =user[“Address”].stringValue
                realm.add(userList,update: true)
            }
        }
    }
}

insertUserData
method方法在循环中多次打开事务。提交事务是有点昂贵的操作

您是否可以尝试在循环之外打开/提交事务? 换句话说,在进入循环之前打开事务,并在循环结束后提交一次事务。例如:

if results.count > 0 {
    if let users = results.array {
        let realm = try! Realm()
        try realm.write {
            for user in users{
                let userList=UserList()
                userList.start=user["Start”].stringValue
                userList.end=user[“End”].stringValue
                userList.name=user[“Name”].stringValue
                userList.address =user[“Address”].stringValue
                realm.add(userList,update: true)
            }
        }
    }
}

我已经通过使用此代码修复了缓慢插入的问题

func addAsBatch<T: Object>(_ data: [T]) {
    if !isRealmAccessible() { return }

    let realm = try! Realm()
    realm.refresh()

    realm.beginWrite()
    for object in data {
        realm.add(object)
    }
    try? realm.commitWrite()
}

我已经通过使用此代码修复了缓慢插入的问题

func addAsBatch<T: Object>(_ data: [T]) {
    if !isRealmAccessible() { return }

    let realm = try! Realm()
    realm.refresh()

    realm.beginWrite()
    for object in data {
        realm.add(object)
    }
    try? realm.commitWrite()
}

这7分钟是否包括下载和解析JSON以及创建表示所需的时间?您将在view controller上看到我的评论,它在那里完成了所有的进度。“print(“Insertion Done”)”大约用了7分钟才出现,“print(“Downloaded JSON”)”只用了几分钟就出现了。所以,是的,两者都有。所以,您并没有真正衡量将给定数据插入领域所需的时间。例如,在慢速连接上,下载7兆字节可能需要“时间”。您应该真正测量将给定数据插入领域所需的时间,而不包括任何其他内容。您可以使用工具来解决这个问题,而无需更改代码,或者在代码中包含“秒表”。我建议使用后者,并将经过的时间记录到控制台。您还可以记录下载的持续时间和解析JSON的持续时间(包括创建表示)。下载不需要太多时间,是的,我测试过。“下载的JSON”只需要10秒。是的,从循环开始插入和解析json时就存在这个问题。有没有办法让它变得完美和优化?从我的代码来看,你觉得怎么样?这是通常的方法吗?如果我做错了,欢迎提供任何指导。代码中有一些地方可以改进,例如,在主线程上插入项目。最好在次线程上提交冗长的操作。然后,您的
didsuccesdownloadingdata
是一个异步函数,但没有完成处理程序。那么,关于性能,我们仍然不清楚,在哪里会花费最多的周期。因此,为了(可能)帮助您,请提供更多详细信息,即成本最高的函数的实际名称。用仪器来解决这个问题。如果Realm是罪魁祸首,那么它应该是
insertUserData
。这7分钟是否包括下载所需的时间以及解析JSON和创建表示所需的时间?您将在view controller上看到我的评论,它完成了所有的进度。“print(“Insertion Done”)”大约用了7分钟才出现,“print(“Downloaded JSON”)”只用了几分钟就出现了。所以,是的,两者都有。所以,您并没有真正衡量将给定数据插入领域所需的时间。例如,在慢速连接上,下载7兆字节可能需要“时间”。您应该真正测量将给定数据插入领域所需的时间,而不包括任何其他内容。您可以使用工具来解决这个问题,而无需更改代码,或者在代码中包含“秒表”。我建议使用后者,并将经过的时间记录到控制台。您还可以记录下载的持续时间和解析JSON的持续时间(包括创建表示)。下载不需要太多时间,是的,我测试过。“下载的JSON”只需要10秒。是的,从循环开始插入和解析json时就存在这个问题。有没有办法让它变得完美和优化?从我的代码来看,你觉得怎么样?这是通常的方法吗?如果我做错了,欢迎提供任何指导。代码中有一些地方可以改进,例如,在主线程上插入项目。最好在次线程上提交冗长的操作。然后,您的
didsuccesdownloadingdata
是一个异步函数,但没有完成处理程序。那么,关于性能,我们仍然不清楚,在哪里会花费最多的周期。因此,为了(可能)帮助您,请提供更多详细信息,即成本最高的函数的实际名称。用仪器来解决这个问题。如果领域是罪魁祸首,那么它应该是
insertUserData
。。在我看到你的成绩之前,我就是这么做的。是的,就像你说的,它非常快,而