什么是Swift中最快的Char-By-Char-Reader

时间:2016-11-06 14:03:15

标签: swift file macos-sierra

我必须在swift中用char读者写一个真正的快速字符。到目前为止,这是我的解决方案。

对于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 个答案:

答案 0 :(得分:0)

我用其中的两个版本更新了存储库:https://github.com/petershaw/charsinfile

在马丁的帮助下,我解决了Rob的代码中的错误。

我测试了一堆不同的文件,两个版本都运行良好。 Rob Napier的代码效率更高!非常感谢,Rob。

感谢大家帮助我找出最快的解决方案。对于快速和可可相关的东西来说,拥有一个非常精彩和礼貌的社区是非常好的。

度过愉快的一周!

ps