2016-04-11 2 views
0

beim Lesen habe ich eine Textdatei mit Zahlen gefüllt und den Inhalt der Datei zu lesen wie folgtLeistungsabfall TXT-Dateien 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 
}} 

Allerdings, wenn ich für die Leistung zu überprüfen, scheint es einen Engpass zu sein an content.componentsSeparatedByString ("\ n") wie unten dargestellt:

Performance Degradation Example

Kann jemand einen Weg für den Umgang mit diesem Problem vorschlagen? oder kann die gesamte Textdatei als doppelt eingelesen wird ein-go mit Werten voneinander getrennt wie folgt:

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] 
+1

warum verwenden Sie nicht eine plist anstelle einer normalen Textdatei? –

+0

@ Leo Dabus, wie kann ich plist verwenden, um Werte zu lesen? Irgendein Tutorial dazu? – Nasiba

Antwort

2

Das liegt daran, dass die Schaffung neue String langsam ist. Ich habe Swifts Quellcode nicht untersucht, um zu verstehen, warum, aber das scheint eine Eigenschaft zu sein, die Swift von ObjC übernommen hat. Außerdem müssen Sie die String in Float konvertieren, was auch keine schnelle Operation ist.

Verwenden NSScanner statt:

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) 
} 

habe ich eine zufällige Datei mit 1 M Zeilen von Zahlen als Eingabe. NSScanner ist etwa 5,3x schneller:

f1: 4.2731032371521 seconds 
f2: 0.82185697555542 seconds 
+0

Schöne Antwort. Ich bin ein wenig überrascht von der Leistung von NSScanner. Ich habe erwartet, dass es noch schneller sein wird, denke ich. – Anurag

+0

Das ist wirklich gut. Zumindest besser als das Erstellen einer neuen String-Methode. Daumen hoch! – Nasiba