ios - 数组到集合的转换需要 20 秒 - Swift 3

标签 ios arrays swift core-data set

为什么从字符串数组到 Set 的转换需要这么长时间?

我正在从 Core Data 读取数据并将获取的结果转换为一个字符串数组,然后从该数组转换为一个集合。在模拟器中从数组到集合的转换大约需要 20 秒。

如果Core Data里面没有数据,我就把一个文本文件读入一个字符串数组,然后把这个数组转成一个集合。在此处进行转换只需不到 1 秒。

Core Data 中的数据与文本文件相同,因为我将加载的文本文件保存到 Core Data 中。那么我正在转换的两个字符串数组应该是相同的吗?

有什么帮助吗?

在大约 20 秒内将数组转换为集合的函数

func coreData() {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate // UIApplication.shared().delegate as! AppDelegate is now UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Sowpods")
    request.returnsObjectsAsFaults = false

    do {
        let results = try context.fetch(request) as? [NSManagedObject] ?? []
        if results.count > 0 {
            print("Results fetched")

            // Load words from Core Data into wordSet
            let wordsArray = results.flatMap { $0.value(forKey: "words") as? String }

            let startTime = CFAbsoluteTimeGetCurrent()
            print("Putting fetched results from Array into Set")
            print("Words in array: \(wordsArray.count)")

            wordSet = Set(wordsArray.map { $0 }) /////// ~20 Seconds ///////////

            let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
            print("Time to put fetched results into wordSet: \(timeElapsed) s")

        } else {
            print("No results fetched from Core Data")
            // Read Dictionary

            wordSet = self.readDictionary(dictionaryFileName: "sowpods", dictionaryFileExtension: "txt")

            // Load words in dictionary into Core Data
            for word in wordSet {
                let newWord = NSEntityDescription.insertNewObject(forEntityName: "Sowpods", into: context)
                newWord.setValue(word, forKey: "words")
            }
            do {
                try context.save()
            } catch {
                print("Failed to save words")
            }
        }
    } catch {
        print("Couldn't fetch results")
    }
}

在 < 1 秒内将数组转换为集合的函数

func readDictionary(dictionaryFileName: String, dictionaryFileExtension: String) -> Set<String> {
    print("Loading Dictionary")
    var wordsArray: [String] = []
    do {
        // This solution assumes  you've got the file in your bundle
        if let path = Bundle.main.path(forResource: dictionaryFileName, ofType: dictionaryFileExtension){
            let data = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
            wordsArray = data.components(separatedBy: .newlines)
        }
    } catch let err as NSError {
        // do something with Error
        print(err)
    }

    let startTime = CFAbsoluteTimeGetCurrent()
    //print("Loading Dictionary")
    print("Words in array: \(wordsArray.count)")

    let dictionarySet = Set(wordsArray.map { $0 }) /////// < 1 Seconds ///////////

    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print("Time to load dictionary Array into Set: \(timeElapsed) s")


    print("Done Loading Dictionary")
    return dictionarySet
}

快速转换日志

  • 没有从 Core Data 获取结果
  • 加载词典
  • 数组中的单词:267627
  • 将字典数组加载到 Set 中的时间:0.7359259724617 秒
  • 完成加载词典

慢速转换日志

  • 获取的结果
  • 从数组中取出结果放入集合中
  • 数组中的单词:267627
  • 将抓取的结果放入wordSet的时间:18.0488159656525 s

最佳答案

会不会是你从数据库中获取的字符串尾部有空格?

这可能会使它们比文本文件中的长得多,从而导致 Set 的散列算法更加努力地工作并可能发生冲突。

在转换为 Set 时,我通过向 238k 单词的单词列表添加 40 个空格来测量时间增加了 3 倍。如果有更多的空格和/或不同的词,这可以部分解释你得到的 20 倍差异。

或者,也许,具有关键字“words”的字典值每条记录包含一个以上的单词(顾名思义),这也会导致数组中的字符串更大,并且可能减少集合中的重复项。

您应该将文件的 dictionarySet 中的元素数量与数据库的 wordSet 进行比较。我怀疑由于某种原因(这也可以解释时差),基于文件的集合中的条目可能会少很多。

关于ios - 数组到集合的转换需要 20 秒 - Swift 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42856754/

相关文章:

java - 使用多线程在数组中查找质数

arrays - 使用 if-else 语句遍历数组 (Swift)

ios - AVPlayerViewController 是否自动带有 AVPlayer 对象?

ios - 如何在没有用户交互的情况下从 iOS 相机捕获图像?

ios - Objective-C :带有 UIImage 的 PushViewController 不工作

ios - SwiftUI 2 生命周期 - 处理自定义 URL 方案

ios - ios中的多个if-else条件

java - java中char数组的使用

ios - Swift: Codable - 提取单个编码 key

ios - 在 Swift 中,是否有更好的方法来初始化 "get"唯一变量?