从Swift中的文本文件加载数字数组

时间:2016-02-13 13:43:14

标签: arrays swift file

我使用Swift函数成功地将文本文件中的数据加载到Double数组中,但速度很慢。有没有办法直接加载数字数据而不使用可能更快的String初始化程序?或者其他任何提高速度的建议?

func arrayFromContentsOfFileWithPath(path: String) -> [Double]? {
    do {
        let content = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
        let stringArray = content.componentsSeparatedByString("\n").map{
            $0.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
        }
        return stringArray.map{Double($0)}.flatMap{$0}
    } catch _ as NSError {
        return nil
    }
}

修改 为了量化一点,数据文件是10000个样本,单个负载的加载时间是0.183秒(根据单元测试中的measureBlock)。相比之下,MATLAB以0.033秒的速度加载文件。以下是数据的前几个样本:

   8.1472369e-01
   9.0579194e-01
   1.2698682e-01
   9.1337586e-01
   6.3235925e-01
   9.7540405e-02
   2.7849822e-01
   5.4688152e-01
   9.5750684e-01
   9.6488854e-01

更新 按照@ appzYourLife的建议来组合映射(我使用.flatMap{Double($0)})并使用Release版本,加载时间现在是0.119秒。好多了,但仍然是MATLAB时间的4倍,这是非常意外的。

1 个答案:

答案 0 :(得分:3)

您可以使用NSScanner()快速读取数据。 scanDouble() 方法跳过前导空格,因此没有中间字符串或数组 需要:

func arrayFromContentsOfFileWithPath(path: String) -> [Double]? {
    do {
        let content = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
        let scanner = NSScanner(string: content)
        var doubleArray = [Double]()
        var value = 0.0
        while scanner.scanDouble(&value) {
            doubleArray.append(value)
        }
        return doubleArray
    } catch _ as NSError {
        return nil
    }
}

在我的测试中,在Release配置中读取10,000个样本 在0.0034秒内完成,相比之下,您的代码为0.077秒, 这是一个超过20倍的改进。

更新 Swift 3:

func arrayFromContentsOfFileWithPath(path: String) -> [Double]? {
    guard let content = try? String(contentsOfFile:path, encoding: .utf8) else {
        return nil
    }
    let scanner = Scanner(string: content)
    var doubleArray = [Double]()
    var value = 0.0
    while scanner.scanDouble(&value) {
        doubleArray.append(value)
    }
    return doubleArray
}