2016-11-06 42 views
0

我必須通過字符閱讀器快速寫出一個真正的快速字符。這是我迄今爲止的解決方案。什麼是Swift中最快的Char-By-Char-Reader

對於一個1.4MB的文件,我得到它在0m0.932s。對於一個150MB的文件,它需要1m42.931s

你知道更快的解決方案嗎?

import Foundation 
class CharReader { 

let encoding : String.Encoding 
let chunkSize : Int 
var fileHandle : FileHandle! 
let buffer : NSMutableData! 
var atEof : Bool = false 
var characterPointer: UnsafeMutablePointer<Character> 
var startPointer: UnsafeMutablePointer<Character> 

var stored_cnt: Int = 0; 
var stored_idx: Int = 0; 

init?(path: String, encoding: String.Encoding = String.Encoding.utf8, chunkSize : Int = 1024) { 
    self.chunkSize = chunkSize 
    self.encoding = encoding 
    characterPointer = UnsafeMutablePointer<Character>.allocate(capacity: chunkSize) 
    startPointer = characterPointer 
    if let fileHandle = FileHandle(forReadingAtPath: path), 
     let buffer = NSMutableData(capacity: chunkSize){ 
     self.fileHandle = fileHandle 
     self.buffer = buffer 
    } else { 
     self.fileHandle = nil 
     self.buffer = nil 
     return nil 
    } 
} 

deinit { 
    self.close() 
} 

func nextChar() -> Character? { 

    if atEof { 
     return nil 
    } 

    if stored_cnt > (stored_idx + 1) { 
     stored_idx += 1 
     let char = characterPointer.pointee 
     characterPointer = characterPointer.successor() 
     return char 
    } 

    let tmpData = fileHandle.readData(ofLength: (chunkSize)) 
    if tmpData.count == 0 { 
     atEof = true 
     return nil 
    } 

    if let s = NSString(data: tmpData, encoding: encoding.rawValue) as String! { 
     stored_idx = 0 
     let characters = s.characters 
     stored_cnt = characters.count 

     characterPointer = startPointer 
     characterPointer.initialize(from: characters) 

     let char = characterPointer.pointee 
     characterPointer = characterPointer.successor() 
     return char 
    } 
    return nil; 
} 


/// Close the underlying file. No reading must be done after calling this method. 
func close() -> Void { 
    fileHandle?.closeFile() 
    fileHandle = nil 
} 

} 

請讓我知道。

我測試類此main.swfit:

import Foundation 

if CommandLine.arguments.count < 2 { 
    print("Too less arguments.") 
    exit(0) 
} 
let file = CommandLine.arguments[1] 

if let aCharReader = CharReader(path: file) { 
defer { 
    aCharReader.close() 
} 
while let char = aCharReader.nextChar() { 
    continue 
} 
} 

該項目在GitHub上:https://github.com/petershaw/charsinfile

非常感謝, PS

+1

你的文件有多大?你能把它完全讀入一個字符串嗎? (順便說一句,代碼看起來很模糊,是從http://stackoverflow.com/a/24648951/1187415獲得的嗎?) –

+0

取決於從字節到多個集合 –

+1

它是純ASCII還是包含任意Unicode字符? –

回答

0

我更新了兩個版本的庫它:https://github.com/petershaw/charsinfile

在Martin的幫助下,我修復了Rob代碼中的錯誤。

我測試了一堆不同的文件,兩個版本都正常工作。 Rob Napier的代碼更高效!非常感謝,Rob。

感謝大家,幫助我找出最快的解決方案。在這裏,有一個如此精彩和有禮貌的社區來爲迅速和可可相關的東西打氣。

祝您有個愉快的周!

ps

+0

我只是好奇:在這裏你說變體「b」(使用Rob的代碼中的StreamGenerator/UnicodeScalarGenerator)是最快的。但你最近的問題http://stackoverflow.com/q/43772575/1187415引用變體「a」(使用你的CharReader)。是否有特殊的理由繼續使用你的變體而不是使用更快的變體? –

相關問題