[英]Performance degradation on reading .txt files in Swift
我有一個充滿數字的文本文件,並按如下方式讀取文件內容
func arrayFromContentsOfFileWithName(fileName: String) -> [String]? {
guard let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "txt") else {
return nil
}
do {
let content = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
return content.componentsSeparatedByString("\n")
} catch _ as NSError {
return nil
}}
但是,當我檢查性能時,content.componentsSeparatedByString(“ \\ n”)似乎存在瓶頸,如下所示:
有人可以提出解決此問題的方法嗎? 或者可以一次將整個文本文件讀為雙倍,並且將值分開,如下所示:
let B1: [Float] = [0.0584000014, 0.0905999988, 0.0916000009, 0.0640999973, 0.0824000016, 0.0960000008, 0.0776999965, 0.0936999992, 0.0908999965, 0.0568999983, 0.0654999986, 0.0535999984, 0.0901999995, 0.0724999979, 0.104900002, 0.0798000023, 0.0962999985, 0.0914999992, 0.0680999979, 0.110100001, 0.0648000017, 0.103299998, 0.077200003, 0.0821999982, 0.0778999999, 0.074000001, 0.0710999966, 0.108499996, 0.060899999, 0.0697000027, 0.0841000006, 0.061900001]
那是因為創建新的String
很慢。 我沒有研究Swift的源代碼來理解為什么,但這似乎是Swift從ObjC繼承下來的特征。 最重要的是,您必須將String
轉換為Float
,這也不是一種快速的操作。
改用NSScanner
:
func timeBlock(label: String, block: () -> Void) {
let start = NSDate().timeIntervalSince1970
block()
let end = NSDate().timeIntervalSince1970
print("\(label): \(end - start) seconds")
}
func f1 (fileContent: String) -> [Float] {
return fileContent.componentsSeparatedByString("\n")
.flatMap { Float($0) }
}
func f2 (fileContent: String) -> [Float] {
let scanner = NSScanner(string: fileContent)
var result = [Float]()
while !scanner.atEnd {
var x: Float = 0
scanner.scanFloat(&x)
result.append(x)
}
return result
}
do {
let content = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
timeBlock("f1") { f1(content) }
timeBlock("f2") { f2(content) }
} catch let error as NSError {
print(error.localizedDescription)
}
我創建了一個隨機文件,其中包含100萬行數字作為輸入。 NSScanner
大約是5.3倍速度快:
f1: 4.2731032371521 seconds
f2: 0.82185697555542 seconds
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.