我使用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倍,这是非常意外的。
答案 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
}