【问题标题】:Splitting string into array string.components(separtedBy: ",") consumes more time将字符串拆分为数组 string.components(separtedBy: ",") 会消耗更多时间
【发布时间】:2020-02-01 02:09:09
【问题描述】:

我有一个包含 18000 行的文本文件,其中包含城市名称。每行都有城市名称、州、纬度、经度等。下面是执行此操作的函数,如果我不实现string.components(separtedBy: ", ") 加载功能非常快,但实现它需要时间,这会使我的 UI 冻结。正确的做法是什么? string.components(separtedBy: ", ") 有那么贵吗?

我分析了应用程序,这条线在整个功能中将 string.components(separtedBy: ", ") 缩短了 2.09 秒中的 1.45 秒。

func readCitiesFromCountry(country: String) -> [String] {
        var cityArray: [String] = []
        var flag = true
        var returnedCitiesList: [String] = []

        if let path = Bundle.main.path(forResource: country, ofType: "txt") {
            guard let streamReader = StreamReader(path: path) else {fatalError()}
            defer {
                streamReader.close()
            }
            while flag {
                if let nextLine = streamReader.nextLine() {
                    cityArray = nextLine.components(separatedBy: ",") // this is the line taking a lot of time, without this function runs pretty fast
                    if (country == "USA") {
                        returnedCitiesList.append("\(cityArray[0]) , \(cityArray[1]) , \(cityArray[2])")
                    } else {
                        returnedCitiesList.append("\(cityArray[0]) , \(cityArray[1])")
                    }
                   //returnedCitiesList.append(nextLine)
                } else {
                    flag = false
                }
            }
        } else {
            fatalError()
        }

        return returnedCitiesList
    }

代码中使用的StreamReader可以在这里找到。它有助于逐行读取文件 Read a file/URL line-by-line in Swift

这个问题不是关于如何将字符串拆分为数组 Split a String into an array in Swift? ,而是为什么拆分在给定函数中需要更多时间。

【问题讨论】:

  • 什么是StreamReader
  • 将其移至后台线程,以免您的 UI 冻结。
  • @MartinR 我已经编辑了问题并附上了链接。我想,我正在使用你的解决方案。
  • @Willeke,不,不是。我已经编辑了这个问题。请检查!
  • DispatchQueue.global(qos: .userInitiated).async { [weak self] in guard let self = self else { return } //your code for lengthy task

标签: arrays swift string cocoa io


【解决方案1】:

NSString.components(separatedBy:) 返回一个[String],它要求从原始字符串复制所有片段的内容,并将其粘贴到新分配的字符串中。这会减慢速度。

您可以通过将这项工作放在后台线程上来解决症状(UI 冻结),但这只会将问题排除在错误的位置(仍然存在低效复制),并使事情变得复杂(异步代码永远不会有趣)。

相反,您应该考虑使用String.split(separator:maxSplits:omittingEmptySubsequences:),它返回[Substring]。每个子字符串只是原始字符串内存的一个视图,它存储相关范围,因此您只能看到由Substring 建模的String 部分。这里发生的唯一内存分配是为数组分配的。

希望这足以将您的代码加速到可接受的水平。如果没有,您应该结合这两种解决方案,并使用split off-thread。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 2012-02-22
    • 2020-01-30
    相关资源
    最近更新 更多